Python 为什么元类不&x27;不行?
在阅读了Django的部分源代码之后,我想做一些测试,并在下面编写代码,看看元类是如何工作的: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
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):
...