python - Python 中的元类是什么?

标签 python oop metaclass python-class python-datamodel

在 Python 中,元类是什么,我们用它们做什么?

最佳答案

元类是类的类。类定义类的实例(即对象)的行为方式,而元类定义类的行为方式。类是元类的实例。

虽然在 Python 中您可以为元类使用任意可调用对象(如 Jerub 所示),但更好的方法是使其成为实际的类本身。 type是 Python 中常见的元类。 type本身就是一个类,它是它自己的类型。您将无法重新创建类似 type 的内容。纯粹在 Python 中,但 Python 有点作弊。要在 Python 中创建自己的元类,您真的只想继承 type .

元类最常用作类工厂。当您通过调用类创建对象时,Python 会通过调用元类创建一个新类(当它执行“class”语句时)。结合正常__init____new__因此,元类允许您在创建类时做“额外的事情”,例如使用某些注册表注册新类或完全用其他内容替换该类。

class语句被执行,Python首先执行class的主体语句作为一个普通的代码块。生成的命名空间(一个 dict)保存了类的属性。元类是通过查看 future 类的基类来确定的(元类是继承的),在 __metaclass__类的属性(如果有)或 __metaclass__全局变量。然后使用类的名称、基类和属性调用元类以实例化它。

然而,元类实际上定义了一个类的类型,而不仅仅是它的工厂,所以你可以用它们做更多的事情。例如,您可以在元类上定义普通方法。这些元类方法类似于类方法,因为它们可以在没有实例的类上调用,但它们也不像类方法,因为它们不能在类的实例上调用。 type.__subclasses__()type 上的方法示例元类。您还可以定义正常的“魔术”方法,例如 __add__ , __iter____getattr__ , 实现或更改类的行为方式。

下面是点点滴滴的汇总示例:

def make_hook(f):
    """Decorator to turn 'foo' method into '__foo__'"""
    f.is_hook = 1
    return f

class MyType(type):
    def __new__(mcls, name, bases, attrs):

        if name.startswith('None'):
            return None

        # Go over attributes and see if they should be renamed.
        newattrs = {}
        for attrname, attrvalue in attrs.iteritems():
            if getattr(attrvalue, 'is_hook', 0):
                newattrs['__%s__' % attrname] = attrvalue
            else:
                newattrs[attrname] = attrvalue

        return super(MyType, mcls).__new__(mcls, name, bases, newattrs)

    def __init__(self, name, bases, attrs):
        super(MyType, self).__init__(name, bases, attrs)

        # classregistry.register(self, self.interfaces)
        print "Would register class %s now." % self

    def __add__(self, other):
        class AutoClass(self, other):
            pass
        return AutoClass
        # Alternatively, to autogenerate the classname as well as the class:
        # return type(self.__name__ + other.__name__, (self, other), {})

    def unregister(self):
        # classregistry.unregister(self)
        print "Would unregister class %s now." % self

class MyObject:
    __metaclass__ = MyType


class NoneSample(MyObject):
    pass

# Will print "NoneType None"
print type(NoneSample), repr(NoneSample)

class Example(MyObject):
    def __init__(self, value):
        self.value = value
    @make_hook
    def add(self, other):
        return self.__class__(self.value + other.value)

# Will unregister the class
Example.unregister()

inst = Example(10)
# Will fail with an AttributeError
#inst.unregister()

print inst + inst
class Sibling(MyObject):
    pass

ExampleSibling = Example + Sibling
# ExampleSibling is now a subclass of both Example and Sibling (with no
# content of its own) although it will believe it's called 'AutoClass'
print ExampleSibling
print ExampleSibling.__mro__

关于python - Python 中的元类是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/100003/

相关文章:

c++ - 使类构造函数私有(private)

python-3.x - 无法 pickle <class 'a class' > : attribute lookup inner class on a class failed

python - 如何设置 Python 的 httplib 使用的信任库?

python - 为什么要创建一个空类,然后实例化它并设置一些属性?

c++ - 在 C++ 中返回一个字符串作为私有(private)继承类

javascript - 更好的 JavaScript 对象初始化

python - 基于连续时间步计算事件

python - Django - 实例需要有主键值才能使用多对多关系

python - 如何做类似 Django 模型的元类技巧

python - Django 动态过滤器集