Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么元类不&x27;不行?_Python_Django - Fatal编程技术网

Python 为什么元类不&x27;不行?

Python 为什么元类不&x27;不行?,python,django,Python,Django,在阅读了Django的部分源代码之后,我想做一些测试,并在下面编写代码,看看元类是如何工作的: class MyMeta(type): def __new__(cls, name, bases, attrs): print cls, name, bases, attrs return super(MyMeta, cls).__new__(cls, name, bases, attrs) class AttrFiled(object): pass cla

在阅读了Django的部分源代码之后,我想做一些测试,并在下面编写代码,看看元类是如何工作的:

class MyMeta(type):
    def __new__(cls, name, bases, attrs):
        print cls, name, bases, attrs
        return super(MyMeta, cls).__new__(cls, name, bases, attrs)

class AttrFiled(object): pass

class Test(MyMeta):
    name = AttrField()
它总是抱怨:

TypeError: __new__() takes at least 2 arguments (1 given)
我添加并修改如下:

def with_metaclass(meta, *bases):  # copied from Django code.
    return meta("NewBase", bases, {})

class Test(with_metaclass(MyMeta)):
    name = CharField()
它是有效的

我也读过这个。 但还是感到困惑


提前谢谢

with_元类最初是在
six
库中引入的(如果我没记错的话),它简化了从Python 2到Python 3的转换。让代码与它们兼容是一个聪明的技巧

Python 2使用以下语法声明元类的使用:

class Foo(object):
    __metaclass__ = FooMeta
Python 3有一个不同的版本:

class Foo(metaclass=FooMeta):
    pass
与_metaclass(meta)
的作用是:它直接使用
meta
metaclass的构造函数创建一个中间临时类,然后您从中派生类。所以蟒蛇2和3都很快乐

您还应该阅读有关此主题的Python文档:


在您的特定情况下,当您编写
类测试(MyMeta)时:
您只是声明了一个元类
测试
,它是从
MyMeta
派生的。要创建一个,您需要编写

 class Test:
     __metaclass__ = MyMeta


取决于您的python版本。或者,如果您不确定是否需要支持Python2,只需将
与\u元类一起使用即可。

谢谢!这真的很有帮助。顺便说一句,为什么它的名字是six.py?2*3 ? :)引用six的官方文件:“six”这个名字来源于2*3等于6的事实。为什么不加呢?乘法更强大,而且,无论如何,“five”已经被Zope five项目抢走了。”;)
 class Test(metaclass=MyMeta):
     ...