Python Metaclass:理解'with_metaclass()'

时间:2013-08-29 14:32:50

标签: python metaclass six-python

我想问一下with_metaclass()调用在类定义中的含义。

E.g:

class Foo(with_metaclass(Cls1, Cls2)):
  • 一个类继承自元类的特殊情况吗?
  • 新类也是元类吗?

2 个答案:

答案 0 :(得分:68)

with_metaclass()six library提供的实用工具类工厂函数,可以更轻松地为Python 2和3开发代码。

它为您创建一个带有指定元类的基类,与您运行代码的Python版本兼容。

从文档中引用:

  

使用基类base和元类metaclass创建一个新类。这被设计用于类声明:

from six import with_metaclass

class Meta(type):
    pass

class Base(object):
    pass

class MyClass(with_metaclass(Meta, Base)):
    pass

这是必需的,因为附加元类的语法在Python 2和3之间发生了变化:

Python 2:

class MyClass(object):
    __metaclass__ = Meta

Python 3:

class MyClass(metaclass=Meta):
    pass

with_metaclass()函数利用了元类是a)由子类继承的事实,以及b)元类可用于生成新类;它通过使用元类作为工厂生成空类来有效地创建新的基类:

def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    return meta("NewBase", bases, {})

{2}和{3}上的NewBase基类的元类是meta

答案 1 :(得分:21)

更新six.with_metaclass()函数已经使用装饰器变体修补,即@six.add_metaclass()。此更新修复了与基础对象相关的一些mro问题。新的装饰器将按如下方式应用:

import six

@six.add_metaclass(Meta)
class MyClass(Base):
    pass

Here are the patch noteshere is a similar, detailed example and explanation用于使用装饰器替代品。