【问题标题】:Determine if a class in python is a metaclass判断python中的类是否是元类
【发布时间】:2016-01-25 15:12:56
【问题描述】:

python中有没有办法判断一个类对象是否是元类?

我知道您可以使用相等运算符进行检查。 metaclass== 类型

但这不包括用户定义的元类。

【问题讨论】:

    标签: python python-3.x metaclass


    【解决方案1】:

    测试对象是否是type的子类:

    issubclass(MetaClass, type)
    

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

    演示:

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

    【讨论】:

      【解决方案2】:

      大多数元类是 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 摆脱了构造函数中的元类参数。
      • @BenHoff:是的。它是 Python 3 代码。 Python 3 在class 语句中使用metaclass(它不是构造函数)。 Python 2 使用__metaclass__ 属性(在类或模块上)。
      • 这不是一个完整的答案,但确实提出了一个重要的观点:您指定作为元类的内容不一定是类;它必须是一个可调用的对象,返回一个与 type 对象具有相同 API 的对象。
      • @chepner:我已经添加了明确的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      相关资源
      最近更新 更多