繁体   English   中英

在评估类时,python中是否有魔术方法?

[英]Is there a magic method in python for when a class is being evaluated?

我有一个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)由于继承链isinstance(self, Mother)Implementation视为从Mother类派生(被视为mro方法解析顺序 ))
使用__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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM