我有一个mixin类,只有在与其他类一起使用时才应该用作接口,例如:
class Mother():
pass
class Child(Mother):
pass
class Mixin():
def __init__(self):
assert isinstance(self, Mother), 'Mixin can only be used with Mother implementations'
super().__init__()
class Implementation(Mixin, Child):
pass
Implementation()
上述方法有效,但只有在实例化Implementation
时,我才能以某种方式在代码执行时评估上述断言?
这一点很重要,这样如果有人错误地实现了类,应用程序就不会运行。
(我不确定我的标题措辞是否正确(
实际上,即使"当Implementation
被实例化时",它也不会工作 - 它会Child
通过类找到与Mother
类的关系(Implementation
继承Child
--->Child
继承Mother
(,
因此isinstance(self, Mother)
由于继承链(被认为是mro
(方法解析顺序((Mother
类Implementation
视为派生__init_subclass__
钩子
:
class Mother():
pass
class Child(Mother):
pass
class Mixin():
def __init_subclass__(cls, **kwargs):
assert isinstance(cls, Mother), 'Mixin can only be used with Mother'
super().__init_subclass__(**kwargs)
class Implementation(Mixin, Child):
pass
Implementation()
抛出:
Traceback (most recent call last):
File ..., in __init_subclass__
assert isinstance(cls, Mother), 'Mixin can only be used with Mother'
AssertionError: Mixin can only be used with Mother
但是,如果您需要允许将Mixin
应用于类及其子类Mother
- 请改用issubclass
调用:
class Mixin():
def __init_subclass__(cls, **kwargs):
assert issubclass(cls, Mother), 'Mixin can only be used with Mother and its subclasses'
super().__init_subclass__(**kwargs)
钩子将应用于类声明阶段(在潜在实例化之前(
你也可以使用元类,它很强大,可以帮助你理解python类。
class Mother():
pass
class Child(Mother):
pass
class Meta(type):
def __new__(meta_cls, name, bases, dct):
if name != "Mixin" and all([not issubclass(b, Mother) for b in bases]):
raise Exception('Mixin can only be used with Mother')
cls = super().__new__(meta_cls, name, bases, dct)
return cls
class Mixin(metaclass=Meta):
pass
class Implementation(Mixin, Child):
pass