在python中评估自身内部的对象

问题描述 投票:0回答:1

我在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))

产生运行时错误?

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

python python-3.x object repr
1个回答
4
投票
  1. 如果你想要这样的东西工作,你需要定义生成有效的a __repr__uable字符串的eval。正如您所见,默认的repr只生成<qualified.classname object at 0xmemoryaddress>,它不是有效的Python代码,因此不能是eval-ed。
  2. 这是一个疯狂的设计,即使你这样做,因为即使你自己可以eval,你刚刚创建了一个无限循环,每个实例尝试创建一个相同的子实例,创建一个相同的子实例,创建无穷无尽的相同的子实例等。

不要这样做。随意定义一个有用的__repr__,但不要尝试evaling它在你自己的__init__

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

© www.soinside.com 2019 - 2024. All rights reserved.