今天我正在玩我的玩具物品
我发现了global
陈述的奇怪之处
这是magic_z.py
class MagicBall(object):
def __del__(self):
global _cat
_cat = self
print "Cat has 9 lives"
m = MagicBall()
以下是实验:
In [1]: from magic_z import *
In [2]: m.__module__
Out[2]: 'magic_z'
In [3]: import magic_z
In [4]: del m
In [5]: _cat
NameError: name '_cat' is not defined
In [6]: magic_z._cat
AttributeError: 'module' object has no attribute '_cat'
In [7]: m2 = magic_z.MagicBall()
In [8]: del m2
Cat has 9 lives
In [9]: _cat
NameError: name '_cat' is not defined
In [10]: magic_z._cat
Out[10]: <magic_z.MagicBall at 0x102eff590>
In [11]: m3 = MagicBall()
In [12]: del m3
Cat has 9 lives
In [13]: _cat
NameError: name '_cat' is not defined
In [14]: m3 = MagicBall()
In [15]: m3.__module__
Out[15]: 'magic_z'
In [16]: magic_z._cat
Out[16]: <magic_z.MagicBall at 0x102e61b50>
似乎global
会将变量更新为target_object.__module__
所指的全局范围
但是当我删除命令m
创建的第一个[1]
对象时,为什么没有发生?
我的意思是python如何知道命令magic_z
导入的[3]
对象不是对象global
中m
语句的目标?
由于m3
和m
的{{1}}属性值均为__module__
?
为什么"magic_z"
从命令m3
导入的MagicBall
对象可以正确触发[1]
函数并更改__del__
对象的_cat
属性?
版本:magic_z
&amp; python 2.7.6
答案 0 :(得分:1)
del x
不一定会破坏x
引用的对象。它只删除引用。当没有更多的引用时,该对象被破坏。
对象m
有两个引用:一个在magic_z
模块中,另一个在主模块中(在导入*
时创建)。主模块中的del m
仅删除其中一个,因此对象仍处于活动状态,并且未调用__del__
。
要调用对象的__del__
,您还需要del magic_z.m
。
m2
和m3
只有一个引用,因此删除该引用会导致对象被破坏 - 尽管在__del__
内创建新引用会取消该修改。< / p>
另请注意,IPython可以保存对命令返回的对象的引用。例如,对_cat
中的Out[10]
对象进行引用,这就是为什么在_cat
被覆盖后不会被删除的原因。如果没有保留此引用,程序将表现不同 - 可能是无限循环。