Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I want to achieve the following:

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

Do I have to copy the attributes one by one or is there a better way to do it?

like image 598
Jürgen Fuchsberger Avatar asked Sep 20 '25 11:09

Jürgen Fuchsberger


1 Answers

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.

like image 106
Martijn Pieters Avatar answered Sep 23 '25 01:09

Martijn Pieters