我想实现以下目标:
#!/usr/bin/python
class SuperHero(object):
def setName(self, name):
self.name = name
def getName(self):
return self.name
class SuperMan(SuperHero):
pass
if __name__ == "__main__":
sh = SuperHero()
sh.setName("Clark Kent")
sm = SuperMan(sh) # This does *not* work in real python
print sm.getName() # prints "Clark Kent"
我是否必须逐个复制属性,或者有更好的方法吗?
答案 0 :(得分:5)
添加一个在__dict__
属性中复制的启动器功能:
class SuperMan(SuperHero):
def __init__(self, source=None):
if source is not None:
self.__dict__.update(source.__dict__)
实例的__dict__
包含所有实例属性,上面只是将所有这些属性复制到新的SuperMan
实例。
演示:
>>> class SuperHero(object):
... def setName(self, name):
... self.name = name
... def getName(self):
... return self.name
...
>>> class SuperMan(SuperHero):
... def __init__(self, source=None):
... if source is not None:
... self.__dict__.update(source.__dict__)
...
>>> sh = SuperHero()
>>> sh.setName("Clark Kent")
>>> sm = SuperMan(sh)
>>> print sm.getName()
Clark Kent
或者,对于更糟糕的黑客攻击,你可以换掉class属性:
sh = SuperHero()
sh.setName("Clark Kent")
sh.__class__ = SuperMan
但这可能会导致更有趣的错误,因为您从未调用SuperMan
初始化程序,因此预期的状态可能不正确。
答案 1 :(得分:0)
我更喜欢明确的解决方案 - 逐个复制。 Martijn Pieters
的解决方案很好,但随着时间的推移,你的__dict__
可能会增长,你可能不想复制它的全部内容(或者更糟糕的是 - 忘记这个事实并经历一些令人讨厌的副作用)。除了Python之禅说:Explicit is better than implicit.
。
旁注 - 你知道属性,对吧?因此,如果您使用它们,您的代码可能会更加pythonic:
class SuperHero(object):
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
sh = SuperHero()
sh.name = "Clark Kent"