在学习Python的数据模型时,我正在使用__new__
方法从现有对象创建对象。以下是一些创建各种类型的新对象的示例:
x = 2; print type(x).__new__(x.__class__)
x = {}; print type(x).__new__(x.__class__)
x = [1,2]; print type(x).__new__(x.__class__)
x = 2.34; print type(x).__new__(x.__class__)
x = '13'; print type(x).__new__(x.__class__)
x = 1.0j; print type(x).__new__(x.__class__)
x = True; print type(x).__new__(x.__class__)
x = (1,2); print type(x).__new__(x.__class__)
然而,以下三个实验给我错误:
x = None; print type(x).__new__(x.__class__)
x = lambda z: z**2; print type(x).__new__(x.__class__)
x = object; print type(x).__new__(x.__class__)
错误分别是:
TypeError: object.__new__(NoneType) is not safe, use NoneType.__new__()
TypeError: Required argument 'code' (pos 1) not found
TypeError: type() takes 1 or 3 arguments
为什么这三个例子不起作用? (注意:对于lambda
示例,我在调用__new__
方法时必须传入代码片段,但我不知道该怎么做。)我使用的是Python 2.6。
请注意,我意识到这不一定是您想要在实际代码中创建新对象的方式,但我的目的不实际,而是要了解低级对象方法的工作原理。
答案 0 :(得分:14)
它没有什么特别之处,只是对于某些类型,有一个默认的"空"这种类型的对象,而对于其他人则没有。您的工作示例基本上等同于:
int()
dict()
list()
float()
str()
complex()
tuple()
。 。 。所有这些工作。您的最后三个示例基本上是尝试创建NoneType,function
和type
的新实例。
types.NoneType()
,您将收到更直接的消息,说明&#34;无法创建NoneType实例&#34;。)< / LI>
function
失败了,因为正如您所见,它需要一个参数,而您却没有提供参数。您需要的是一个代码对象,您可以从现有函数或compile
函数获取该代码对象。 (它还需要一个globals
参数,这可能只是一个字典。)type
失败,因为您没有给出足够的论据。您可以type(foo)
获取foo类型,也可以type(name, bases, dict)
创建新类型(即类)。请注意,在上一个示例中,您采用的是object
类型,它本身就是一种类型。如果改为x = object()
(使x成为单个对象而不是对象类型),那么它将起作用并创建一个&#34;空白&#34;对象
要记住的是,调用__new__
并不是那么神奇。当你直接尝试通过someType()
实例化类型时会发生什么。如果该类型需要参数,则调用__new__
将失败,就像任何其他函数调用将失败一样,如果您没有给它正确的参数,因为type(x).__new__
只是一个函数,就像任何其他函数一样。您可以使用用户定义的类来查看它:
>>> class Foo(object):
... pass
>>> x = Foo(); print type(x).__new__(x.__class__)
<__main__.Foo object at 0x00EB0370>
>>> class Foo(object):
... def __init__(self, someArg):
... pass
>>> class Foo(object):
... def __new__(cls, someArg):
... return super(Foo, cls).__new__(cls)
>>> x = Foo(2); print type(x).__new__(x.__class__)
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
x = Foo(2); print type(x).__new__(x.__class__)
TypeError: __new__() takes exactly 2 arguments (1 given)
在第一种情况下成功了,因为我的班级并不需要论证;它在第二个类中失败了,因为第二个类确实需要参数。
__new__
因任何秘密原因不会失败;它只是失败,因为您尝试实例化的类型需要参数才能构造实例。 (None
案例是唯一一个不同的案例;由于None
是Python中的特殊对象,因此{1}}因特殊原因而失败。