【问题标题】:Is it possible to make metaclass methods participate in method resolution?是否可以让元类方法参与方法解析?
【发布时间】:2016-07-26 10:52:48
【问题描述】:

考虑这个例子:

class Meta(type):
    def method(*_, **__):
        print('Meta')


class A(object):
    __metaclass__ = Meta


class B(object):
    @classmethod
    def method(*_, **__):
        print('B')


class C(A, B):
    pass


C.method() # prints 'B'

这里我们有一个类A,它有方法method,定义在它的元类Meta中。我们有一个类B,它也有一个方法method,但定义为一个类方法。

C,继承自AB,结果具有来自类Bmethod

但如果Amethod 定义为类方法,则C 已从A 继承method

我想找到一种方法让Meta.method 参与继承,就好像它是一个使用这个元类的类的类方法一样。有没有可能?

【问题讨论】:

  • C 也有 Meta 作为它的元类,A 的任何子类也是如此。 C 是否应该表现得像它有自己的 method 定义一样,就像你希望 A 表现得一样?

标签: python metaclass


【解决方案1】:

type 上的方法只有在查找对象本身的属性失败时才会查找;将此与实例属性与类属性进行比较;这是一样的。

如果您需要一种方法来参与 MRO,请将其放在类本身上。元类可以这样做:

class Meta(type):
    def __new__(mcls, name, bases, body):
        cls = super(Meta, mcls).__new__(mcls, name, bases, body)
        if not hasattr(cls, 'method'):
            @classmethod
            def method(*_, **__):
                print('Meta')
            cls.method = method
        return cls

只有当新创建的类还没有这样的方法时,才会将该方法粘贴到新创建的类上;这允许您的类(或任何子类)覆盖元类提供的方法,并防止任何子类在可以被继承的地方得到相同的方法。

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    相关资源
    最近更新 更多