Python默认元类

Python默认元类,python,metaclass,Python,Metaclass,不管类中是否使用了元类,是否可以通过某种方式将python模块或REPL配置为对所有定义的类使用默认元类 class met(type): def __init__(cls, name, bases, dct): super(met, cls).__init__(name, bases, dct) setattr(cls, "_test_member", "test_value") class A(object): pass >>&

不管类中是否使用了元类,是否可以通过某种方式将python模块或REPL配置为对所有定义的类使用默认元类

class met(type):
    def __init__(cls, name, bases, dct):
        super(met, cls).__init__(name, bases, dct)
        setattr(cls, "_test_member", "test_value")

class A(object):
    pass

>>> A._test_member
'test_value'

在Python2.x上,您可以

 __metaclass__ = met
在模块开头,然后以旧式模式定义类:

class A:
    pass
在3.x上,这已经不可能了。而且,“显性比隐性好。”

另一种方法是:

class Object(metaclass=met):  # Py3k syntax
    pass
永远从中继承

注意:调用
type
的子类是使用与Py2k和Py3k兼容的元类的唯一方法。就像in使用Pavel Anossov(现已删除)的评论所作的回答一样:

印刷品

test_value

请注意,一个类只能有一个元类。(毕竟,任何对象只能有一种类型)。但另外,类的元类必须是其所有基元类的(非严格)子类。换句话说,类的元类及其所有基的元类必须是相同的,或者所有这些元类必须是彼此的子类。因此,如果一个类试图使用一个不是
met
子类的元类,那么上述解决方案可能不起作用

比如说,

class met(type):
    def __init__(cls, name, bases, dct):
        super(met, cls).__init__(name, bases, dct)
        cls._test_member = "test_value"

object = met('object', (object,), {})

class someothertype(type): pass

class B(object):
    __metaclass__ = someothertype
提高

TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

有没有办法重新定义内置对象类以使用元类?您可以重新绑定它,就像上面的一条评论中所说的:
object=object
,这将非常危险,容易出错,而且通常是不受欢迎的。@user2357112是的,这就是为什么我要用大写字母
O
来命名它,这样其他人就能知道发生了什么on@dilbert:您的问题要求将
met
作为元类,而不管是否在类中使用元类。注意,对于定义显式元类的类,这个答案不适用于Python2。在这种情况下,unutbu的方法是有效的。我不知道你们可以用对象本身作为基础来重新定义对象。非常狡猾。@PavelAnossov:如果您想发布答案,我将删除此答案。@unutbu:我将
setattr(cls,“\u test\u member”,“test\u value”)
替换为更常见和直接的形式。@EOL:谢谢您的编辑,EOL。(顺便说一句,您的编辑鼓励我采用pep8间距…+1:即使类根据问题的要求定义了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases