我在python中读到了repr()函数。我想过尝试一些事情并考虑在对象内部评估repr()的输出以查看它导致的结果。所以我写了下面的代码:
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))
产生运行时错误?
(此外,了解语言设计者如何考虑允许或限制此类作业将是非常有见地的)
__repr__
uable字符串的eval
。正如您所见,默认的repr
只生成<qualified.classname object at 0xmemoryaddress>
,它不是有效的Python代码,因此不能是eval
-ed。eval
,你刚刚创建了一个无限循环,每个实例尝试创建一个相同的子实例,创建一个相同的子实例,创建无穷无尽的相同的子实例等。不要这样做。随意定义一个有用的__repr__
,但不要尝试eval
ing它在你自己的__init__
。
需要明确的是,self.b = self
与self.b = eval(repr(self))
不是一回事。前者只是创建一个参考周期(在某些情况下本身就存在问题,但通常不会致命)。后者是基于当前对象创建一个全新的对象,当前对象处于构造过程中时,即使它没有导致无限递归的对象构造,在许多情况下也是一个坏主意。