25. Наследование атрибута класса
Условие задачи Дан родительский класс с атрибутом класса. От него наследуются два дочерних класса, в которых собственные атрибуты не объявлены. Нужно определить, какое значение будет выведено при обращении к этому атрибуту через родительский класс и через оба дочерних класса.
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print(Parent.x, Child1.x, Child2.x)
Что будет если мы определим поле х у наследника?
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
А в случае если переопределим у класса от которого наследуемся? (При условии что код выше уже отработал)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
Спойлеры к решению
Подсказки
xобъявлен как атрибут классаParent.- Если у дочернего класса нет собственного
x, Python ищет его у родителя. Child1.x = 2не меняетParent.x, а создаёт или переопределяет атрибутxименно уChild1.- После этого
Child1.xуже берётся из самогоChild1, а не изParent. - Если затем изменить
Parent.x, это повлияет наChild2.x, потому чтоChild2всё ещё берётxу родителя. - На
Child1.xэто уже не повлияет, потому что уChild1есть собственный атрибутx.
Решение
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print(Parent.x, Child1.x, Child2.x)
Результат:
1 1 1
У Child1 и Child2 нет собственного атрибута x, поэтому оба класса берут его у родительского класса Parent.
Дальше:
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Результат:
1 2 1
Строка:
Child1.x = 2
не изменяет Parent.x. Она создаёт собственный атрибут x внутри класса Child1.
Поэтому:
Parent.x = 1
Child1.x = 2
Child2.x = 1
Дальше, при условии что предыдущий код уже выполнился:
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
Результат:
3 2 3
Parent.x изменился на 3.
Child2.x тоже стал 3, потому что Child2 всё ещё не имеет собственного x и берёт значение у Parent.
Child1.x остался 2, потому что у Child1 уже есть собственный атрибут x, который перекрывает родительский.