If you just want to change the class .__name__ , create a decorator that will do this.
from __future__ import print_function def decorate_class(klass): klass.__name__ += 'Dec' return klass class Base(object): def __init__(self): print('Base init') @decorate_class class MyClass(Base): def __init__(self): print('MyClass init') super(MyClass, self).__init__() c = MyClass() cls = c.__class__ print(cls, cls.__name__)
Python 2 exit
MyClass init Base init <class '__main__.MyClassDec'> MyClassDec
Python 3 exit
MyClass init Base init <class '__main__.MyClass'> MyClassDec
Note the difference in cls representation. (I'm not sure why you want to change the class name, although it sounds like a recipe for confusion, but I think this is normal for this simple example).
As others have said, @decorator not intended to subclass. You can do this in Python 3 using the super argument (i.e., super().__init__() ). And you can make it work in both Python 3 and Python 2 by explicitly providing the parent class, rather than using super .
from __future__ import print_function def decorate_class(klass): name = klass.__name__ return type(name + 'Dec', (klass,), {}) class Base(object): def __init__(self): print('Base init') @decorate_class class MyClass(Base): def __init__(self): print('MyClass init') Base.__init__(self) c = MyClass() cls = c.__class__ print(cls, cls.__name__)
Python 2 and 3 output
MyClass init Base init <class '__main__.MyClassDec'> MyClassDec
Finally, if we just call decorate_class using the usual function syntax, and not like @decorator , we can use super .
from __future__ import print_function def decorate_class(klass): name = klass.__name__ return type(name + 'Dec', (klass,), {}) class Base(object): def __init__(self): print('Base init') class MyClass(Base): def __init__(self): print('MyClass init') super(MyClass, self).__init__() MyClassDec = decorate_class(MyClass) c = MyClassDec() cls = c.__class__ print(cls, cls.__name__)
The conclusion is the same as in the latest version.