如何使用语句`global`查找对象的目标范围?

时间:2015-11-10 10:27:58

标签: python scope global

今天我正在玩我的玩具物品 我发现了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]对象不是对象globalm语句的目标? 由于m3m的{​​{1}}属性值均为__module__? 为什么"magic_z"从命令m3导入的MagicBall对象可以正确触发[1]函数并更改__del__对象的_cat属性?

版本:magic_z&amp; python 2.7.6

1 个答案:

答案 0 :(得分:1)

del x不一定会破坏x引用的对象。它只删除引用。当没有更多的引用时,该对象被破坏。

对象m有两个引用:一个在magic_z模块中,另一个在主模块中(在导入*时创建)。主模块中的del m仅删除其中一个,因此对象仍处于活动状态,并且未调用__del__

要调用对象的__del__,您还需要del magic_z.m

m2m3只有一个引用,因此删除该引用会导致对象被破坏 - 尽管在__del__内创建新引用会取消该修改。< / p>

另请注意,IPython可以保存对命令返回的对象的引用。例如,对_cat中的Out[10]对象进行引用,这就是为什么在_cat被覆盖后不会被删除的原因。如果没有保留此引用,程序将表现不同 - 可能是无限循环。