确定Python中的一个类是否是元类。

3

在Python中,有没有一种方法可以确定一个类对象是否是元类?

我知道你可以使用等号运算符进行检查。 元类 == type

但这并不适用于用户定义的元类。

2个回答

6

测试对象是否为type子类:

issubclass(MetaClass, type)

这将对所有元类, 包括 type 本身返回 True

演示:

>>> class Meta(type): pass
...
>>> class Foo(object): pass
...
>>> issubclass(Meta, type)
True
>>> issubclass(Foo, type)
False

4

大多数元类都是type的子类(issubclass(metaklass, type)),但并非全部:

>>> def logging_meta(name, bases, namespace, **kwd):
...     print(name, bases, namespace, kwds)
...     return type(name, bases, namespace, **kwds)
... 
>>> class C(metaclass=logging_meta):
...     a = 1
... 
C () {'__module__': '__main__', '__qualname__': 'C', 'a': 1} {}
>>> issubclass(logging_meta, type)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class

即,答案是“任何可调用的对象,例如一个带有一个__call__()方法的类,它接受与type()相同的参数并返回一个类对象即可”:
>>> class C(metaclass=lambda *a: lambda *a: None): pass
... 
>>> C()
>>> type(C)
<class 'function'>

这是有效的 Python 3 代码吗?我以为 Python 3 在构造函数中已经摆脱了元类参数。 - Ben Hoff
@BenHoff:是的,这是Python 3代码。Python 3在class语句中使用metaclass(它不是构造函数)。Python 2使用__metaclass__属性(在类或模块上)。 - jfs
1
这并不完全是一个答案,但确实提出了一个重要的问题:您所指定的元类不一定是一个类;它只需要是一个可调用对象,该对象返回与 type 对象具有相同 API 的对象。 - chepner
@chepner:我已经添加了明确的答案。 - jfs

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