有没有一种很好的方式来表达Python中“覆盖说明符”的反义词?

时间:2015-08-12 03:20:00

标签: python override decorator python-decorators

C ++ 11添加了override specifier,这是一个方法覆盖父类方法的承诺。我想表达与此相反的意思,即任何父类都不实现方法。我可以在没有元类的情况下表达它,例如使用装饰器吗?

这就是我目前正在做的事情

class EchoSoma(Soma):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        assert not hasattr(super(), 'inject_basic_evidence')

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

1 个答案:

答案 0 :(得分:2)

不,如果没有元类,你就无法做到。

在类块内执行的代码不知道超类,以及"这个类"还没有存在。您需要一些只能由元类提供的预处理或后处理。或者,您需要将超类传递给装饰器,装饰器需要重建MRO,最有可能是通过构建临时类并检查其__mro__属性。这比编写你试图避免使用的元类要简单得多。

签入__init__是不够的,因为只有在实例化类时才会这样做,而不是在最初创建类时。

元类解决方案看起来像这样:

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寻找装饰方法。