我有一个TypeClass来制作类:
class MyMetaClass(type):
def __new__(cls, *args, **kwargs):
print('call __new__ from MyMetaClass.')
return type(cls.__name__, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
但是在使用时:
Foo= MyMetaClass('Foo', (), {'name':'pd'})
Run Code Online (Sandbox Code Playgroud)
提出错误:
TypeError: type() takes 1 or 3 arguments
Run Code Online (Sandbox Code Playgroud)
如果改变它:
class MyMetaClass(type):
def __new__(cls, *args, **kwargs):
print('call __new__ from MyMetaClass.')
return type(cls.__name__, (), {})
Run Code Online (Sandbox Code Playgroud)
它会起作用!哪里有问题?
该__new__方法通过3个位置参数args; 类名,基类和类体.该cls参数绑定到元类,所以MyMetaClass在这里.
您正在为该序列添加另一个名称; 删除名称,或从中删除第一个参数args:
class MyMetaClass(type):
def __new__(cls, *args, **kwargs):
print('call __new__ from MyMetaClass.')
return type(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
要么
class MyMetaClass(type):
def __new__(cls, *args, **kwargs):
print('call __new__ from MyMetaClass.')
return type(cls.__name__, *args[1:], **kwargs)
Run Code Online (Sandbox Code Playgroud)
该cls参数是元类对象然而,所以除非你想所有的类被称为MyMetaClass我与第一个选项棒.
请参阅Python数据模型的Customizing类创建部分:
这些步骤必须在元类的
__new__()方法中执行 -type.__new__()然后可以从此方法调用以创建具有不同属性的类.此示例在创建类之前向类字典添加新元素:Run Code Online (Sandbox Code Playgroud)class metacls(type): def __new__(mcs, name, bases, dict): dict['foo'] = 'metacls was here' return type.__new__(mcs, name, bases, dict)
__new__()是一个静态方法(特殊的,因此您不需要声明它),它将请求实例的类作为其第一个参数.其余参数是传递给对象构造函数表达式的参数(对类的调用).
其中哪个的请求的实例的类是您的元类(产生一个类对象).
演示:
>>> class MyMetaClass(type):
... def __new__(cls, *args, **kwargs):
... print('call __new__ from MyMetaClass.')
... return type(*args, **kwargs)
...
>>> class Foo(object):
... __metaclass__ = MyMetaClass
...
call __new__ from MyMetaClass.
>>> Foo
<class '__main__.Foo'>
>>> class MyMetaClass(type):
... def __new__(cls, *args, **kwargs):
... print('call __new__ from MyMetaClass.')
... return type(cls.__name__, *args[1:], **kwargs)
...
>>> class Foo(object):
... __metaclass__ = MyMetaClass
...
call __new__ from MyMetaClass.
>>> Foo
<class '__main__.MyMetaClass'>
>>> # Note the ^^^^^^^^^^^^ class.__name__ attribute here
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3367 次 |
| 最近记录: |