T开发者_Python百科he following code doesn't work in Python 3.x, but it used to work with old-style classes:
class Extender:
def extension(self):
print("Some work...")
class Base:
pass
Base.__bases__ += (Extender,)
Base().extension()
Question is simple: How can I add dynamically (at runtime) a super class to a class in Python 3.x?
But I'm ready the answer will be hard! )
It appears that it is possible to dynamically change Base.__bases__
if Base.__base__
is not object
. (By dynamically change, I mean in such a way that all pre-existing instances that inherit from Base
also get dynamically changed. Otherwise see Mykola Kharechko's solution).
If Base.__base__
is some dummy class TopBase
, then assignment to Base.__bases__
seems to work:
class Extender(object):
def extension(self):
print("Some work...")
class TopBase(object):
pass
class Base(TopBase):
pass
b=Base()
print(Base.__bases__)
# (<class '__main__.TopBase'>,)
Base.__bases__ += (Extender,)
print(Base.__bases__)
# (<class '__main__.TopBase'>, <class '__main__.Extender'>)
Base().extension()
# Some work...
b.extension()
# Some work...
Base.__bases__ = (Extender, TopBase)
print(Base.__bases__)
# (<class '__main__.Extender'>, <class '__main__.TopBase'>)
Base().extension()
# Some work...
b.extension()
# Some work...
This was tested to work in Python 2 (for new- and old-style classes) and for Python 3. I have no idea why it works while this does not:
class Extender(object):
def extension(self):
print("Some work...")
class Base(object):
pass
Base.__bases__ = (Extender, object)
# TypeError: __bases__ assignment: 'Extender' deallocator differs from 'object'
As for me it is impossible. But you can create new class dynamically:
class Extender(object):
def extension(self):
print("Some work...")
class Base(object):
pass
Base = type('Base', (Base, Extender, object), {})
Base().extension()
精彩评论