Yon*_*tan 4 python inheritance class registration
我有python类树,每个树都由一个抽象基类和许多派生的具体类组成.我希望通过基类方法可以访问所有具体类,并且我不想在子类创建期间指定任何内容.
这就是我想象的解决方案:
class BaseClassA(object):
# <some magic code around here>
@classmethod
def getConcreteClasses(cls):
# <some magic related code here>
class ConcreteClassA1(BaseClassA):
# no magic-related code here
class ConcreteClassA2(BaseClassA):
# no magic-related code here
Run Code Online (Sandbox Code Playgroud)
尽可能地,我更喜欢将"魔术"写成一种设计模式.我希望能够将它应用于不同场景中的不同类树(即添加一个与"BaseClassB"及其具体类相似的树).
谢谢上网!
这是一个使用PEP 487__init__subclass__中定义的现代 python (3.6+) 的简单解决方案。它允许您避免使用元类。
class BaseClassA(object):
_subclasses = []
@classmethod
def get_concrete_classes(cls):
return list(cls._subclasses)
def __init_subclass__(cls):
BaseClassA._subclasses.append(cls)
class ConcreteClassA1(BaseClassA):
pass # no magic-related code here
class ConcreteClassA2(BaseClassA):
pass # no magic-related code here
print(BaseClassA.get_concrete_classes())
Run Code Online (Sandbox Code Playgroud)
您可以使用元类:
class AutoRegister(type):
def __new__(mcs, name, bases, classdict):
new_cls = type.__new__(mcs, name, bases, classdict)
#print mcs, name, bases, classdict
for b in bases:
if hasattr(b, 'register_subclass'):
b.register_subclass(new_cls)
return new_cls
class AbstractClassA(object):
__metaclass__ = AutoRegister
_subclasses = []
@classmethod
def register_subclass(klass, cls):
klass._subclasses.append(cls)
@classmethod
def get_concrete_classes(klass):
return klass._subclasses
class ConcreteClassA1(AbstractClassA):
pass
class ConcreteClassA2(AbstractClassA):
pass
class ConcreteClassA3(ConcreteClassA2):
pass
print AbstractClassA.get_concrete_classes()
Run Code Online (Sandbox Code Playgroud)
我个人非常警惕这种魔法.不要在代码中加入太多内容.