Eclipse平台,Python 3.3。
我已经创建了下面的代码来演示使用全局变量和python unittest时的问题。我想知道为什么第二次单元测试(直接重复第一次)导致
NameError: global name '_fred' is not defined
尝试评论第二次测试,一切都通过确定 (注意:我在实例后添加了一个简短的摘要,说明真实代码试图实现的内容,希望它在那里不那么突兀,因为它与问题无关)
''' Global Problem
'''
import unittest
_fred = None
def start():
global _fred
if _fred is None:
_fred = 39
_fred += 3
def stop():
global _fred
if _fred is not None:
del _fred
class Test(unittest.TestCase):
def setUp(self):
start()
def tearDown(self):
stop()
def test_running_first_time(self):
assert(_fred == 42)
def test_running_second_time(self):
assert(_fred == 42)
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
在实际代码中,_fred是变量引用从Thread派生的类的实例(参见我在那里做的)并在start方法中分配。
_fred = MyThreadClass()
同步队列有第二个全局
该方法在专用线程上启动和停止控制处理队列项。 'stop'停止处理,同时允许添加项目
Thread for Thread仅允许单个调用启动。因此,要重新启动处理,我需要一个新的Thread实例。因此使用
if _fred is None:
和
del _fred
没有用于猜测我的主要语言的奖品
答案 0 :(得分:4)
del _fred
未将_fred
设置为None
或类似的内容。它删除了名称_fred
。完全。对于全球化而言,它似乎从未存在过。对于本地人来说,就好像它从未被分配过一样。要将变量设置为None
,请执行以下操作:
_fred = None
答案 1 :(得分:2)
问题是del _fred
。由于您告诉解释器_fred
是全局的,_fred
将从全局字典中删除,并且未设置为None
。当你告诉一个函数某个东西是全局的时候它就会记住它,所以当它对该变量名执行操作时,它会全局地执行它。即使global _fred
未定义,start
中的_fred
也不会影响_fred
的值。这只是解释者的首要任务。
答案 2 :(得分:2)
执行此操作时:
def stop():
global _fred
if _fred is not None:
del _fred
您实际上正在访问此模块全局变量字典,并且当fred不是None时,您将从模块中删除变量 fred(它不再存在)。单元测试为每个测试方法调用setUp和tearDown,第一个方法的tearDown将从模块变量dict中删除_fred,这将导致第二个setUp失败。
这可能就是你想做的事情:
if _fred is not None:
_fred = None
另一方面,我更喜欢把start和stop放到一个新类中,然后创建这个类的_fred全局实例:
class Fred:
def __init__(self):
self.state = None
def start(self):
if self.state is None:
self.state = 39
self.state += 3
def stop(self):
if self.state is not None:
self.state = None
_fred = Fred()
class Test(unittest.TestCase):
def setUp(self):
_fred.start()
def tearDown(self):
_fred.stop()
def test_running_first_time(self):
self.assertEqual(_fred.state, 42)
def test_running_second_time(self):
self.assertEqual(_fred.state, 42)