在另一个函数中导入函数时出现问题
在另一个函数中导入函数时出现问题
我有两个文件,blah.py 包含以下内容:
def blah(): print("外部 blah") return "6"
而test.py 包含以下内容:
def blah(): print("内部 blah") return "5" if __name__ == '__main__': try: from blah import blah except: pass num = blah() print(num)
当我运行这段代码时,我得到以下输出:
外部 blah 6
当我将 blah.py 文件重命名为 blaat.py 以使其无法访问时,我得到以下输出:
内部 blah 5
现在,如果我将 test.py 更改为:
def blah(): print("内部 blah") return "5" def blater(): try: from blah import blah except: pass num = blah() print(num) if __name__ == '__main__': try: from blater import blater except: pass blater()
当 blah.py 可访问时,它可以正常工作,但是当 blah.py 不可访问时,我会收到错误消息:
Traceback (most recent call last): File "./test.py", line 27, inblater() File "./test.py", line 16, in blater num = blah() UnboundLocalError: local variable 'blah' referenced before assignment
为什么会这样?我错过了调用函数的微妙差别吗?
问题:在一个函数中导入另一个函数时出现的问题。
原因:在编译过程中,名称是在作用域中添加的,而不是在执行过程中添加的。因此,在这个例子中,即使导入失败,名称仍将被添加到作用域中。
解决方法:在第一种情况下,这不是一个问题,因为函数定义中创建的名称"blah"和导入语句中创建的名称"blah"在同一个作用域中。
在第二种情况下,函数定义中创建的名称"blah"被添加到全局作用域中,而导入语句中创建的名称"blah"被添加到"blater"的本地作用域中。因此,即使导入失败,"blater"的本地作用域中仍然存在名称"blah",这会阻止Python在全局作用域中查找"blah"。由于"blah"未设置,因此会抛出"UnboundLocalError"错误。
如果您想更深入地了解这个问题,以下是一些帮助我更好理解的链接:
- "Introduction to python bytecode":介绍Python字节码的文章。
- "dis module documentation":dis模块的官方文档。
- "inspect module documentation":inspect模块的官方文档。
- "Python Data model":了解名称的存储方式的Python数据模型。