构造一个子类 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
的 '__init__'
中查找 A
实例状态方面的信息,因为大多数常规的、简单的 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 是一个特殊的方法,类可以定义它。如果定义了这个方法,它将被(例如通过pickle)用于获取序列化目的下实例的状态(否则,实例的__dict__被视为实例的“状态”)。如果它返回一个字典,则update调用会更新self的状态;但如果类还定义了一个接受任何其他类型参数的__setstate__方法(因此此代码首先尝试该路线,然后退回到update可能性),那么它也可以返回其他任何东西。请注意,在这种使用情况下,特殊方法中的任一或两者都将从A继承-我不会在B中定义/覆盖它们(当然,除非有进一步微妙的目标要通过这种方式实现)。
是否值得使用这四行"神奇"代码来代替我最初建议的简单赋值呢?大多数情况下不值得——简单性是首选。但如果A做任何特殊操作或受外部代码影响其状态,那么这个解决方案可能更强大且更通用(这正是您通过接受其复杂性购买的)。因此,您必须知道是否适用于后一种情况(然后“使用特殊状态相关方法的大炮”),或者A及其实例是“非常正常的普通实例”,在这种情况下,我强烈建议选择简单和清晰。
a
应该代表什么? - SilentGhost__init__()
方法,Guy。不要将其与继承语法混淆。 - Xavier Ho