我想弄清楚这里发生了什么。我想保留字符串键和类值的映射(也称为dict),以便在运行时创建新实例。我省略了Farm类定义,这在这里并不重要。
好了,给出以下代码:
d = dict(farm = Farm)
# Dynamic instantiation with assignment
f1 = d["farm"]()
f2 = d["farm"]()
print(f1)
print(f2)
# Dynamic instantiation without assignment
print(d["farm"]())
print(d["farm"]())
我得到下一个输出:
C:\Python3\python.exe E:/Programacion/Python/PythonGame/Prueba.py
<BuildingManager.Farm object at 0x00F7B330>
<BuildingManager.Farm object at 0x00F7B730>
<BuildingManager.Farm object at 0x00F7BAD0>
<BuildingManager.Farm object at 0x00F7BAD0>
Process finished with exit code 0
请注意,当我打印它们而未分配时,ref是相同的(0x00F7BAD0)。
为什么Python中的实例化总是返回相同的对象?
答案 0 :(得分:2)
为什么Python中的实例化总是返回相同的对象?
没有。再看一下输出返回的ID:
只回收最后一个。它仍然不是同一个对象。
那么为什么两个最后的ID相同,但前两个是不同的?
在前两种情况下,您将分配给变量。该变量保留用于完整执行程序。因此,这两个对象中的每一个都是唯一的,并且仍然是唯一的。
然后,有第三个实例化(第一个print语句)。此对象已创建,打印,但从未分配到任何变量。因此,在打印之后,Python可以忘记它。确实如此。 在最后一个实例化(第二个print语句)中,Python创建了一个 new Farm实例,但为它分配了与未保存的实例相同的ID(编号3)。这只是方便,而且在引擎盖下,这也可能是有效的(内存空间可用。) 因此,您会看到一个回收的ID,即使它实际上是一个新实例。
答案 1 :(得分:1)
Python没有返回相同的对象,它返回了一个刚刚创建到与前一个地址相同的新对象。执行print(d["farm"]())
时,将创建新对象并打印其地址。由于没有引用它,只要print
返回就可以进行垃圾收集。当第二个print(d["farm"]())
被执行时,恰好将对象创建为相同的地址。请注意,当您将返回值分配给变量时,这不会发生,因为只要有对象的引用,就无法对对象进行垃圾回收。