Python: How to copy all attibutes from base class to derived one

后端 未结 2 1697
Happy的楠姐
Happy的楠姐 2021-01-20 06:29

I want to achieve the following:

#!/usr/bin/python
class SuperHero(object): 
    def setName(self, name):
        self.name = name
    def getName(self):
            


        
相关标签:
2条回答
  • 2021-01-20 06:46

    Add a initiator function that copies across the __dict__ attribute:

    class SuperMan(SuperHero): 
        def __init__(self, source=None):
            if source is not None:
                self.__dict__.update(source.__dict__)
    

    The __dict__ of an instance holds all instance attributes, the above merely copies over all of those attributes to the new SuperMan instance.

    Demo:

    >>> 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
    

    Or, for a more terrible hack, you could swap out the class attribute:

    sh = SuperHero()
    sh.setName("Clark Kent")
    sh.__class__ = SuperMan
    

    but that can lead to more interesting bugs as you never called the SuperMan initializer and thus the expected state might be incorrect.

    0 讨论(0)
  • 2021-01-20 07:02

    I'd prefer explicit solution - copying one by one. Martijn Pieters's solution is nice, but with time your __dict__ may grow and you may not want to copy all it's content (or worse - forget about this fact and experience some nasty side effects). Besides the Zen of Python says: Explicit is better than implicit..

    Side note - you are aware of properties, right? So your code could be more pythonic if you used them:

    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" 
    
    0 讨论(0)
提交回复
热议问题