Python 2.7调用reload()时出现NameError: global name未定义的问题求助
解决Python 2.7中QThread内重载模块的NameError问题
这个问题我之前也碰到过,核心是变量作用域混淆导致的,我来一步步拆解原因和解决办法:
问题根源
你把import foo写在了MyQThread类的顶层作用域里,这时候foo是作为类的属性存在的,而不是全局变量或者run方法的局部变量。当你在run方法里直接调用reload(foo)时,Python会默认去全局作用域查找foo,找不到就抛出了NameError。
解决方案
方案1:将模块导入移到全局作用域(推荐)
这是最清晰、最不容易出错的方式,把import foo放到文件顶部的全局区域,这样run方法就能直接访问到全局的foo模块:
from PyQt4 import QtCore, QtGui import foo # 移到全局作用域 class MyQThread(QtCore.QThread): def __init__(self, parent=None): super(MyQThread, self).__init__(parent) def run(self): reload(foo) # 现在可以直接访问全局的foo print("Reloaded") # ...后续逻辑
方案2:明确引用类作用域的模块
如果你坚持要在类内部导入模块,那么在reload时需要明确指定是类的属性,比如通过类名或者self.__class__来引用:
from PyQt4 import QtCore, QtGui class MyQThread(QtCore.QThread): import foo # 类作用域内导入 def __init__(self, parent=None): super(MyQThread, self).__init__(parent) def run(self): reload(MyQThread.foo) # 明确引用类的foo属性 # 或者用 self.__class__.foo 也可以 print("Reloaded") # ...后续逻辑
方案3:在run方法内局部导入
如果只需要在run方法里使用这个模块,可以直接在方法内部先导入再重载:
from PyQt4 import QtCore, QtGui class MyQThread(QtCore.QThread): def __init__(self, parent=None): super(MyQThread, self).__init__(parent) def run(self): import foo # 局部导入到run方法的作用域 reload(foo) print("Reloaded") # ...后续逻辑
额外提醒
Python 2.7的reload是内置函数,但要注意:重载模块并不会更新已经创建的模块实例,只是重新加载模块的代码。如果你的foo模块里有全局状态或者已初始化的对象,重载后这些内容的行为可能不符合预期,使用时要谨慎。
内容的提问来源于stack exchange,提问作者Mr Pickel
相关产品推荐
相关产品推荐

