当一个类被另一个类扩展时,有没有办法在Python中执行一些代码?更准确地说,我想自动保留扩展基类的所有类的寄存器。因此,我想写一些类似的东西:
class Base:
subclasses = {}
@classmethod
def extending(cls, subclass):
cls.subclasses[subclass.__name__] = subclass
class Extend1(Base):
pass
class Extend2(Base):
pass
在这段代码之后,我希望Base.subclasses包含指向两个扩展类的链接。
你能建议一种让这项工作的方法吗?或者,也许,提供一个等效的解决方案?
答案 0 :(得分:3)
这显然是元类的应用程序。也就是说,如果你想改变classe C的行为,你应该改变C本身的类,这是一个元类,通常是type
。这是一个解决方案的存根:
class Meta(type):
def __new__(cls, clsname, bases, dct):
res = type.__new__(cls, clsname, bases, dct)
for cls in bases:
if isinstance(cls, Meta):
try:
cls.extending(res)
except AttributeError:
pass
return res
我继承自type
,使得元类拦截类的创建并将创建的类存储在基类_subclass
属性中。然后用
class Base(object):
__metaclass__ = Meta
subclasses = {}
@classmethod
def extending(cls, subclass):
cls.subclasses[subclass.__name__] = subclass
class Extend1(Base):
pass
class Extend2(Base):
pass
然后
>>> Base.subclasses
{'Extend1': __main__.Extend1, 'Extend2': __main__.Extend2}
非常重要的一点:元类是inherited
(我认为这不是正确的术语)。因此,Extend1
和Extend2
也是Meta
的实例:
>>> type(Extend1)
<class '__main__.Meta'>
答案 1 :(得分:2)
实际上,如果你只对子类感兴趣,python可以自动给你。所有新样式类都有一个__subclasses__()
方法,它返回所有类的直接后代。
>>> class Base(object):
... pass
...
>>> class Child(Base):
... pass
...
>>> Base.__subclasses__()
[<class '__main__.Child'>]
>>>