Подходящая (Python 2.7) версия вашего кода будет выглядеть следующим образом:
class A(object):
def __init__(self, firstname):
self.firstname = firstname
class B(A):
def __init__(self, lastname):
super(B, self).__init__(firstname)
self.lastname = lastname
parent = A('somefirstname')
child = B('somefirstname', 'somelastname')
print(child.firstname)
print(child.lastname)
Но я подозреваю, что вы действительно не понимаете ОО и особенно не наследование.В комментарии вы пишете:
Я считаю невероятно непродуктивным, что мне приходится создавать экземпляр родительского класса внутри дочернего класса.
Где вы это видели???Вызов __init__
суперкласса НЕ "создает экземпляр родительского класса", он просто применяет класс родителя __init__
к текущему дочернему экземпляру.Как еще можно правильно инициализировать дочерний экземпляр?
Неужели нет способа просто передать экземпляр родительского объекта дочернему классу и просто добавить новые атрибуты?
да, вы можете - просто вызовите метод класса и передайте экземпляр в качестве первого аргумента:
parent = A("firstname")
B.__init__(parent, "lastname")
print(parent.firstname, parent.lastname)
, но это НЕ будет делать то, что вы ожидаете - parent
останется экземпляром A
(хотя и с дополнительными атрибутами):
print(type(parent))
Кроме того, ваш класс B
не совместим с A
, поэтому он не является правильным подтипом A
(согласно принципу подстановки Лискова).Технически это не является незаконным, и не обязательно является проблемой, но наследование связано не только с повторным использованием реализации, но и с подтипом (наследование обозначает отношение is a
, поэтому «B наследует от A» означает, что «B»это (вид) А ").Так как наследование реализации в основном является ограниченным составом / делегированием падежа, вы можете дважды подумать о семантике своих моделей, прежде чем выбирать между наследованием и составлением / делегированием.
EDIT - это:
class A(object):
def __init__(self, firstname):
self.firstname = firstname
class B(A):
def __init__(self, parent, lastname):
self.lastname = lastname
A.__init__(self, parent.firstname)
parent = A('somefirstname')
child = B(parent, 'somelastname')
это очень плохо спроектированная версия этого:
class A(object):
def __init__(self, firstname):
self.firstname = firstname
class B(A):
def __init__(self, firstname, lastname):
super(B, self).__init__(firstname)
self.lastname = lastname
parent = A('somefirstname')
child = B(parent.firstname, 'somelastname')
И она плохо спроектирована, потому что она требует наличия A
экземпляра - или чего-либо с атрибутом «firstname» - для создания B
экземпляра, когда все, что нужно B
- это имя.Вы всегда хотите ограничить связывание / зависимости между объектами до необходимого минимума.
FWIW также похоже, что вы путаете два разных восприятия «parent» и «child».
В OOP «parent» и «child» - это около классов , а не экземпляров и не подразумевают каких-либо прямых связей между экземплярами базового и производного классов (обратите внимание на использование «base» и «производного» вместо «parent» и «child» - этоменее двусмысленно).
Похоже, вы хотите смоделировать некоторые отношения между экземплярами («Люк, я твой отец», кто-нибудь?), где «ребенок» как «родитель» (а не «это").Наследование не является подходящим инструментом, вы хотите вместо него составление / делегирование:
class Father(object):
def __init__(self, firstname):
self.firstname = firstname
class Child(object):
def __init__(self, father, lastname):
self.father = father # composition
self.lastname = lastname
@property
def firstname(self):
# delegation
return self.father.firstname
vador = Father("Vador")
luke = Child(vador, "Luke")