Python:如何将所有属性从基类复制到派生类

时间:2014-02-11 10:48:33

标签: python class inheritance

我想实现以下目标:

#!/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"

我是否必须逐个复制属性,或者有更好的方法吗?

2 个答案:

答案 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"