如何基于“类A中的一个”构造子类B的对象,完全取决于后者如何保持状态(如果有的话),以及如何最好地到达该状态并复制它。在您的示例中,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是一种特殊的方法,类可以定义它——如果它们定义了,就使用它(例如通过pickling)来“获取”它们的实例的状态,以便进行序列化(否则,实例的__dict__将被视为实例的“状态”)。它可能返回一个dict(在这种情况下,.update调用更新了self的状态),但是如果类还定义了一个接受它的__setstate__,它也可能返回任何其他内容(因此,在返回到更新可能性之前,这段代码首先尝试该路由)。注意,在这个用例中,任何一个或两个特殊方法都将从A继承——我不会在B中定义/重写它们(当然,除非有更微妙的目标要通过这种方式实现;-)。
用这四行“魔法”代替我最初建议的简单作业值得吗?大多数情况下,不——简单是最好的。但是,如果A做了什么特殊的事情,或者受到外部代码改变其状态的影响,那么这个解决方案可能会更强大、更通用(这就是您通过接受其复杂性而购买的东西)。所以,你必须知道后一种情况是否适用(然后是特殊的与国家相关的方法的“大炮”),或者A及其实例是否是“非常普通的普通实例”,在这种情况下,我强烈建议选择简单和清晰。