有没有一种很好的方式来表达“一个”的反面;覆盖说明符";用Python?

有没有一种很好的方式来表达“一个”的反面;覆盖说明符";用Python?,python,overriding,decorator,python-decorators,Python,Overriding,Decorator,Python Decorators,C++11添加了,这是一个方法重写父类方法的承诺。我想表达与此相反的观点,即方法不是由任何父类实现的。我可以在没有元类的情况下表达它吗,比如用一个装饰器 这就是我目前正在做的 类回声体(Soma): 定义初始(自我,**kwargs): 超级() 断言非hasattr(super(),“注入基本证据”) def注入基本证据(自身、基本证据): 超级()火灾(基本火灾) 不,没有元类就不能这样做 在类块内执行的代码不知道超类,而且“此类”还不存在。您需要一些只能由元类提供的预处理或后处理。或者,您

C++11添加了,这是一个方法重写父类方法的承诺。我想表达与此相反的观点,即方法不是由任何父类实现的。我可以在没有元类的情况下表达它吗,比如用一个装饰器

这就是我目前正在做的

类回声体(Soma): 定义初始(自我,**kwargs): 超级() 断言非hasattr(super(),“注入基本证据”) def注入基本证据(自身、基本证据): 超级()火灾(基本火灾)
不,没有元类就不能这样做

在类块内执行的代码不知道超类,而且“此类”还不存在。您需要一些只能由元类提供的预处理或后处理。或者,您需要将超类传递给decorator,decorator需要重建MRO,最有可能的方法是构建一个临时类并检查其
\uuuuu MRO\uuu
属性。这比仅仅编写您试图避免的元类更混乱

签入
\uuuu init\uuuu
不够好,因为这只在实例化类时完成,而不是在最初创建类时完成

元类解决方案如下所示:

class NoOverrideMeta(type):
    def __new__(mcs, name, bases, dct, no_override=None):
        if no_override is None:
            no_override = []
        cls = super().__new__(name, bases, dct)
        for meth_name in no_override:
            assert not hasattr(super(cls, cls), meth_name)
        return cls

class EchoSoma(Soma, metaclass=NoOverideMeta, no_override=['inject_basic_evidence']):

    def inject_basic_evidence(self, basic_in):
        super().fire(basic_in)

这个例子通过关键字参数传递方法名,这是3.x中的一个新特性。装饰师会更干净,但会更复杂一些;你可以迭代dct,寻找修饰过的方法。

啊,很好。在Python3中如何使用元类?谢谢。我喜欢避免使用元类,直到这样的东西被接受:这篇文章的作者相当乐观。元类不会很快消失,也不会建议消除它们。我也不想消除它们。元类的问题是,当您需要两个元类时,您需要使用元类继承,这非常烦人。例如,将您的
NoOverrideMeta
与Python的
abc.ABCMeta
相结合是正常的。