python - Python中的元类是什么?

标签 python oop metaclass python-datamodel

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

最佳答案

元类是类的类。类定义类的实例(即对象)的行为,而元类定义类的行为。类是元类的实例。
在Python中,可以对元类使用任意的可调用函数(比如Jerubshows),更好的方法是使它成为一个实际的类本身。type是Python中常用的元类。type本身就是一个类,它是自己的类型。您将无法纯用Python重新创建类似type的内容,但Python有点作弊。要在Python中创建自己的元类,您只需要将type子类化。
元类最常用作类工厂。当通过调用类创建对象时,Python通过调用元类创建一个新类(当它执行“class”语句时)。因此,元类与普通的__init____new__方法相结合,允许您在创建类时执行“额外的操作”,例如用某个注册表注册新类或用其他完全替换类。
当执行class语句时,Python首先将class语句的主体作为普通代码块执行。结果命名空间(dict)保存类的属性。元类是通过查看要成为类的基类(元类是继承的)、要成为类的__metaclass__属性(如果有的话)或__metaclass__全局变量来确定的。然后使用类的名称、基和属性调用元类来实例化它。
然而,元类实际上定义了类的类型,而不仅仅是类的工厂,因此您可以对它们做更多的工作。例如,可以在元类上定义普通方法。这些元类方法类似于类方法,因为它们可以在没有实例的类上调用,但它们也不同于类方法,因为它们不能在类的实例上调用。type.__subclasses__()type元类上的一个方法示例。您还可以定义普通的“magic”方法,如__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/47984772/

相关文章:

Java:如何连续扫描输入?

oop - DDD - 持久性模型和领域模型

python - 如何将参数从 Python 3.x 中的类定义传递给元类?

python - 使用类访问对象列表的属性

c++ - qRegisterMetaType - 类、类*或两者

python - 如何让我的 python 应用程序在继续之前等待某个子进程

python - 如何提高 Google App Engine 上 request_logs 的吞吐量

python - 识别 Pandas 中两个重叠列的不同映射

python - 使用 tkinter 我希望能够使用相同的单选按钮从用户那里获取两个输入

python - 在 Python 中混合 OOP 和过程编程(或一般混合编程风格)是不好的做法吗