Python元类可以继承吗?

5

classes can inherit..

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??
   '''

如果可能,如何实现抽象单例类?


你试过了吗?它应该可以工作。你的示例元类只是比普通类更复杂,因为它使用了多重继承。 - Blckknght
没有,我还没有完全理解在元类继承的情况下__new__方法调用将如何链接,正如我所问的那样,我不确定应该在AbstractSingleton中放置什么代码。 - Arun Kaliraja Baskaran
只要在两个元类中都使用了 super,它很可能就能正常工作。 - Blckknght
谁建议您需要元类来创建单例模式?那个人应该被禁止编写任何 Python 代码。 - jsbueno
1个回答

6
是的,这是可能的。但首先需要明确一点:在Python中创建单例,你不应该使用元类。单例是一个简单的概念,只需要自定义一个__new__方法就足够了,不需要使用元类。
这个简单的四行代码的普通类可以作为一个mixin,将任何派生类转换成"单例"类——在创建第一个实例后,不会再创建其他实例,并且总是返回第一个实例。
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):
    ...

恰巧的是,本周早些时候我正好使用了这个用例作为Python中“元元类”可以实现的示例。通过在要合并到另一个元类的元类上拥有特殊的“元元类”,它可以使用运算符“ + ”创建派生的组合元类,就像在示例中使用ABCMeta一样。

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

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

在这里查看答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接