【问题标题】:Can python metaclasses inherit?python元类可以继承吗?
【发布时间】:2018-02-08 23:02:36
【问题描述】:

类可以继承..

class Base:
    def __init__(self,name):
        self.name = name

class Derived1(Base):
    def __init__(self,name):
        super().__init__(name)


class Derived2(Base):
    def __init__(self,name):
        super().__init__(name)

元类也可以做类似的事情吗?

我有一个要求,我的一些类必须既是抽象基类又是我自己的元类(比如单例类型..)

可以吗

class Singleton(type): 
   '''
   implementation goes here..
   '''

class AbstractSingleton(Singleton,ABCMeta):
   '''
   What code should go here??
   '''

如果可能的话,如何实现 AbstractSingleton 类?

【问题讨论】:

  • 你试过了吗?它应该工作。您的示例元类仅比您的普通类更复杂,因为它使用多重继承。
  • 不,我没有.. 我不完全理解在元类继承的情况下 new 方法调用将如何被链接,正如我所问的那样,我不确定应该使用什么代码在 AbstractSingleton 里面..
  • 只要您在两个元类中都使用super,它可能就可以工作。
  • 谁建议您需要单例元类?应该禁止那个人编写任何 Python 代码。

标签: python-3.x metaclass


【解决方案1】:

是的,有可能。

但首先要做的是:

不应该在 Python 中使用元类来创建单例。 单例是一个简单的概念,只需自定义 __new__ 方法就足够了 - 不需要元类。

这个简单的 4 行 normal 类代码可以用作 mixin,并将任何派生类转换为“单例”类 - 在创建第一个实例之后,不再创建更多实例,a nd 总是返回第一个实例:

class SingletonBase:
   def __new__(cls, *args, **kw):
        if not "instance" in cls.__dict__:
              cls.instance = super().__new__(cls, *args, **kw)
        return cls.instance

现在,如果您有另一个元类的真实案例并且需要将其与 ABCMeta 或其他元类结合起来,您所要做的就是创建一个继承自两个元类的第三个元类 - 如果它们都是以良好的方式使用super,它会起作用。

class SingletonMeta(type):
    def __call__(cls, *args, **kw):
         # You know - you _really_ should not be using metaclasses for singletons.
         if not "instance" in cls.__dict__:
             cls.instance = super().__call__(*args, **kw)
         return cls.instance


class SingletonAbstractMeta(SingletonMeta, abc.ABCMeta):
    pass

class SingleAbstractBase(metaclass=SingleAbstractMeta):
    ...

纯属巧合,本周早些时候,我正好使用 this 用例作为 Python 中“元元类”可以实现的示例。通过对一个想要组合到另一个元类的特殊“元元类”(我什至在示例中使用 ABCMeta),它可以只使用运算符“+”创建派生的组合元类,就像在

class SingletonMeta(type, metaclass=MM):
    ...

class AbstractSingletonBase(metaclass=SingletonMeta + abc.ABCMeta):
    # code here.

Check the answer here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2017-02-21
    相关资源
    最近更新 更多