【问题标题】:Is there a nice way to express the opposite of an "override specifier" in Python?有没有一种很好的方式来表达 Python 中“覆盖说明符”的反面?
【发布时间】:2015-08-12 03:19:59
【问题描述】:

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)

【问题讨论】:

    标签: python overriding decorator python-decorators


    【解决方案1】:

    不,没有元类你不能这样做。

    在类块中执行的代码不知道超类,并且“这个类”还不存在。您需要一些只能由元类提供的预处理或后处理。或者,您需要将超类传递给装饰器,这将需要重建 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 寻找修饰的方法。

    【讨论】:

    • 啊,好点。你会如何在 Python 3 中使用元类?
    • 谢谢。在接受这样的事情之前,我喜欢避免使用元类:groups.google.com/forum/#!searchin/python-ideas/metaclass/…
    • 那篇文章的作者相当乐观。元类不会很快消失,PEP 487 不建议消除它们。
    • 我也不想消除它们。元类的问题是当你需要其中两个时,你需要使用元类继承,这很烦人。例如,将您的 NoOverrideMeta 与 Python 的 abc.ABCMeta 结合起来是很正常的。
    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多