gpt4 book ai didi

python - 为继承mixin类的类动态添加类变量

转载 作者:太空狗 更新时间:2023-10-30 02:41:15 24 4
gpt4 key购买 nike

我有一个 mixin 类,它为继承类添加了一些功能,但是 mixin 需要存在一些类属性,为简单起见,我们假设只有一个属性 handlers。所以这就是 mixin 的用法:

class Mixin:
pass

class Something(Mixin):
handlers = {}

如果不定义 this,mixin 将无法运行,但我真的不想在每个要使用 mixin 的类中指定 handlers。所以我通过编写元类解决了这个问题:

class MixinMeta:
def __new__(mcs, *args, **kwargs):
cls = super().__new__(mcs, *args, **kwargs)
cls.handlers = {}
return cls

class Mixin(metaclass=MixinMeta):
pass

这完全符合我的要求。但我认为这可能会成为一个大问题,因为元类不能很好地协同工作(我读到各种元类冲突只能通过创建一个解决这些冲突的新元类来解决)。

此外,我不想让 handlers 属性成为 Mixin 类本身的属性,因为这意味着必须在内部按类名存储处理程序Mixin 类,使代码复杂一点。我喜欢让每个类在它们自己的类上都有它们的处理程序 - 这使得使用它们更简单,但显然这有缺点。

我的问题是,什么是更好的实现方式?我对元类还很陌生,但它们似乎很好地解决了这个问题。但是,在处理复杂的层次结构而不必定义各种元类来解决这些冲突时,元类冲突显然是一个大问题。

最佳答案

您的问题非常真实,Python 人员已经在 Python 3.6(仍未实现)上想到了这一点。现在(直到 Python 3.5),如果你的属性可以等到你的类第一次实例化时才存在,你可以把 c​​od 放在你的 mixin 类本身的 __new__ 方法上创建一个(类)属性- 从而避免(额外的)元类:

class Mixin:
def __new__(cls):
if not hasattr(cls, handlers):
cls.handlers = {}
return super().__new__(cls)

对于 Python 3.6,PEP 487定义一个 __init_subclass__ 特殊方法来继续 mixin 类主体。这个特殊的方法不会为 mixin 类本身调用,但会在 type.__new__ 方法(“根”元类)的末尾为从你的 mixin 继承的每个类调用。

class Mixin:
def __init_subclass__(cls, **kwargs):
cls.handlers = {}
return super().__init_subclass__(**kwargs)

根据 PEP 的背景文本,这样做的主要动机正是导致您提出问题的原因:在需要简单自定义类创建时避免使用元类,以减少需要不同的机会元类,从而引发元类冲突的情况。

关于python - 为继承mixin类的类动态添加类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39878756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com