gpt4 book ai didi

使用 __new__ 来自现有对象的 Python 对象

转载 作者:太空狗 更新时间:2023-10-29 17:31:14 24 4
gpt4 key购买 nike

在学习 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。

请注意,我知道这不一定是您希望在实际代码中创建新对象的方式,但我的目的并不实际,而是了解低级对象方法的工作原理。

最佳答案

没什么特别的,只是对于某些类型有该类型的默认“空”对象,而对于其他类型则没有。您的工作示例基本上等同于:

int()
dict()
list()
float()
str()
complex()
tuple()

. . .所有这些都有效。您的最后三个示例基本上是在尝试创建 NoneType、functiontype 的新实例。

  1. NoneType 失败的原因很独特,因为 None 是单例——NoneType 类型只能有一个实例,即 None 对象。 (您得到的特定错误消息有点奇怪,但是如果您执行 types.NoneType(),您会得到一条更直接的消息“无法创建 NoneType 实例”。)
  2. function 失败,因为如您所见,它需要一个参数,而您没有提供。您需要的是一个代码对象,您可以从现有函数或 compile 函数中获取它。 (它还需要一个 globals 参数,它可以只是一个字典。)
  3. type 失败,因为您没有提供足够的参数。您可以执行 type(foo) 来获取 foo 的类型,或者执行 type(name, bases, dict) 来创建新类型(即类)。

请注意,在上一个示例中,您使用的是 object 类型,它本身就是一种类型。如果您改为执行 x = object()(使 x 成为一个单独的对象而不是对象类型),那么它将起作用并创建一个“空白”对象。

要记住的是,调用 __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__ 不会因为任何 secret 原因而失败;它只是失败了,因为您尝试实例化的类型需要参数才能构造实例。 (None 情况是这里唯一不同的情况;该情况确实因特殊原因而失败,因为 None 是 Python 中的特殊对象。)

关于使用 __new__ 来自现有对象的 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12658824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com