如何将子类boo的属性挂载到父类foo上,实现foo.boo式调用?
解决方法
要实现让子类boo作为基类foo的类属性,从而通过foo.boo.example_attribute访问子类成员,有两种规范且扩展性强的实现方式:
方式一:使用装饰器自动注册
写一个装饰器,在定义子类时自动将其挂载到父类的属性中:
def register_to_parent(parent_cls): def decorator(sub_cls): # 将子类以自身类名作为属性名,挂载到父类上 setattr(parent_cls, sub_cls.__name__, sub_cls) return sub_cls return decorator class foo: # this class puts things into the env object for use in other files @register_to_parent(foo) class boo(foo): example_attribute = "Blah Blah"
运行print(foo.boo.example_attribute),会输出Blah Blah。后续新增其他继承自foo的子类时,只需给子类加上这个装饰器,就能自动挂载到foo中,无需手动修改foo类。
方式二:使用元类自动注册
通过元类控制类的创建过程,让子类在定义时自动注册到父类:
class RegisterMeta(type): def __new__(meta, name, bases, attrs): # 创建子类 sub_cls = super().__new__(meta, name, bases, attrs) # 遍历子类的所有基类,将子类挂载到每个基类上 for base in bases: setattr(base, name, sub_cls) return sub_cls class foo(metaclass=RegisterMeta): # this class puts things into the env object for use in other files class boo(foo): example_attribute = "Blah Blah"
这种方式更自动化,只要子类继承foo,就会自动被挂载为foo的类属性。同样运行print(foo.boo.example_attribute)会得到预期输出,新增子类时无需额外操作,扩展性拉满。
这两种方式都比手动显式定义foo.boo更规范,符合代码的开闭原则,新增子类时不需要修改父类代码。
内容的提问来源于stack exchange,提问作者mbedross
相关产品推荐
相关产品推荐

