在python中评估对象内部



我读过python中的repr()函数。我想做一些实验,并想在对象内部评估rep()的输出,看看它会产生什么结果。所以我写了以下代码:

class no : 
def __init__(self,a) :
self.a = a
self.b = eval(repr(self))
k = no(2) 
print(k.b.a)

我预计在调用init时,对象已经创建。因此,考虑在一个已经创建的对象中创建一个相同类的新对象。

然而,行中:

k = no(2)

我收到一个运行时错误:

Traceback (most recent call last):
File "classofpy.txt", line 54, in <module>
k = no(2)
File "classofpy.txt", line 52, in __init__
self.b = eval(repr(self))
File "<string>", line 1
<__main__.no object at 0x0385F690>
^

然而,我不明白为什么当调用init时,对象已经创建好了,它却抱怨对象不存在。

但是更换时:

self.b = eval(repr(self))

通过

self.b = self

一切都很好。

这种行为背后的原因可能是什么?尽管在语义上都是

self.b = self 

以及self.b=eval(repr(self))

意思相同。我想我在这里的细节可能是错的,比如,self.b=eval(repr(self))在内存布局方面可能有其他含义,可能与创建副本对象的含义不同,但这正是我发布这个问题的目的。

那么为什么

self.b = eval(repr(self))

产生运行时错误?

(此外,了解语言设计者如何考虑允许或限制此类任务将是非常有见地的)

  1. 如果您想让这样的东西发挥作用,您需要定义一个__repr__,它可以生成一个有效的、eval可用的字符串。正如您所看到的,默认的repr只生成<qualified.classname object at 0xmemoryaddress>,这不是有效的Python代码,因此不能是eval-ed
  2. 即使你这样做,这也是一个疯狂的设计,因为即使你自己可以eval,你也只是创建了一个无限循环,在这个循环中,每个实例都试图创建一个相同的子实例,它创建了一个子实例,创建了一子实例,等等,无限

不要这样做。可以随意定义一个有用的__repr__,但不要在自己的__init__中尝试eval

需要明确的是,self.b = selfself.b = eval(repr(self))不是一回事。前者只是创建了一个参考循环(在某些情况下,这本身就是一个问题,但通常不会致命)。后者是在当前对象的基础上创建一个全新的对象,考虑到当前对象正在构建过程中,这在许多情况下都是一个坏主意,即使它没有导致无限递归的对象构建。

相关内容

  • 没有找到相关文章

最新更新