Ответ 1
Как вы строите объект подкласса B
"на основе" одного из классов A
зависит исключительно от того, как последнее сохраняет состояние, если оно есть, и как вам лучше всего добраться до этого состояния и скопировать его. В вашем примере экземпляры A
не имеют состояния, поэтому в B
'__init__'
нет необходимости работать. В более типичном примере скажем:
class A(object):
def __init__(self):
self._x = 23
self._y = 45
def f(self):
print 'in f,', self._x
def h(self):
print 'in h,', self._y
состояние будет находиться в двух атрибутах экземпляра _x
и _y
, поэтому это то, что вам нужно скопировать:
class B(A):
def __init__(self, a):
self._x = a._x
self._y = a._y
def f(self):
print 'in B->f,', self._x
Это самый распространенный и нормальный подход, когда подкласс принимает и непосредственно реализует свою зависимость от состояния над суперклассом - он очень прямолинейный и линейный.
Обычно вы просматриваете аспекты состояния экземпляра A
в A
'__init__'
, потому что самый обычный, простой код Python устанавливает состояние экземпляра при инициализации (атрибуты могут быть добавлены и удалены позже или даже из кода вне класса тело, но это не является общим и вообще нецелесообразным).
Можно добавить небольшое прикосновение к "магии" (программирование на основе интроспекции), например...:
class B1(A):
def __init__(self, a):
try: s = a.__getstate__()
except AttributeError: s = a.__dict__
try: self.__setstate__(s)
except AttributeError: self.__dict__.update(s)
getstate - это специальный метод, который могут определять классы - если они это делают (например, путем травления), чтобы "получить состояние" своих экземпляров для целей сериализации (в противном случае экземпляр __dict__
считается экземпляром "state" ). Он может вернуть dict (в этом случае вызов .update
обновляет состояние self
), но он может также вернуть что-либо еще, если класс также определяет __setstate__
, который его принимает (так что этот код сначала пытается этот маршрут, прежде возврат к возможности обновления). Обратите внимание, что в этом случае использование одного или обоих специальных методов будет унаследовано от A
- я бы не определял/не переопределял их в B
(если только не будут достигнуты такие тонкие цели, которые, конечно,).
Стоит ли использовать эти четыре строки "магии" вместо простых назначений, которые я впервые предложил? В основном, нет - простота предпочтительнее. Но если A
делает что-то особенное или подвержено внешнему коду, изменяющему его состояние, это решение может быть более мощным и общим (то, что вы покупаете, принимая его усложнение). Итак, вы должны знать, применяется ли последнее дело (а затем "пойти на большие пушки" специальных методов, связанных с государством), или если A
и его экземпляры "довольно нормальные ванильные", и в этом случае я настоятельно рекомендовал бы вместо этого выбирать простоту и ясность.