【发布时间】:2014-07-24 01:55:59
【问题描述】:
我最近发现了一些有趣的行为,这让我想知道对象如何知道存在哪些全局变量。例如,假设我有一个文件“test.py”:
globalVar = 1
toDelete = 2
class Test(object):
classVar = 3
def runTest1(self):
print globalVar
print toDelete
print missingVar
def runTest2(self):
print self.classVar
print toCreate
print missingVar
然后在交互式外壳中我这样做:
>>> import test
>>> tester = test.Test()
>>> tester.runTest1()
1
2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 10, in runTest1
print missingVar
NameError: global name 'missingVar' is not defined
>>> tester.runTest2()
3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 14, in runTest2
print toCreate
NameError: global name 'toCreate' is not defined
没什么好奇怪的。然后我把“test.py”的前几行改成这样:
globalVar = 4
toCreate = 5
class Test(object):
classVar = 6
现在回到交互式外壳:
>>> reload(test) # test = reload(test) gives the same result
<module 'test' from 'test.py'>
>>> tester.runTest1()
4
2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 10, in runTest1
print missingVar
NameError: global name 'missingVar' is not defined
>>> tester.runTest2()
3
5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 15, in runTest2
print missingVar
NameError: global name 'missingVar' is not defined
>>> dir(test)
['Test', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'globalVar', 'toCreate', 'toDelete']
所以tester 现在知道toCreate,它是在tester 本身创建之后出现的。它仍然知道toDelete,因为重新加载模块显然不会影响已删除的全局变量。这是一个转折点:
>>> import sys
>>> import importlib
>>> del(sys.modules['test']) # remove cached version
>>> test = importlib.import_module('test') # same result if I don't have 'test = '
>>> tester.runTest1()
None
None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 10, in runTest1
print missingVar
NameError: global name 'missingVar' is not defined
>>> tester.runTest2()
3
None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 15, in runTest2
print missingVar
NameError: global name 'missingVar' is not defined
>>> dir(test)
['Test', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'globalVar', 'toCreate']
从sys.modules 中删除模块,然后重新导入模块会导致所有全局变量变为None。
另外有趣的是,如果我删除test 和sys.modules['test'],它仍然知道一段时间内的变量值。过了一会儿(我假设模块被垃圾收集需要多长时间),值变为None。重新导入模块会导致垃圾收集(或正在发生的任何事情)立即发生。
那么tester 是如何发现一个新的全局变量正在创建的,然后一旦模块消失了,为什么它仍然知道哪些变量存在,即使它不再知道它们持有什么值?
【问题讨论】:
-
对象对范围一无所知。 功能做。
-
@delnan 函数是对象,所以... *ducks and runs*
标签: python python-2.7 global-variables python-import python-module