在另一个函数中导入函数时出现问题

10 浏览
0 Comments

在另一个函数中导入函数时出现问题

我有两个文件,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, in 
    blater()
  File "./test.py", line 16, in blater
    num = blah()
UnboundLocalError: local variable 'blah' referenced before assignment

为什么会这样?我错过了调用函数的微妙差别吗?

0
0 Comments

问题:在一个函数中导入另一个函数时出现的问题。

原因:在编译过程中,名称是在作用域中添加的,而不是在执行过程中添加的。因此,在这个例子中,即使导入失败,名称仍将被添加到作用域中。

解决方法:在第一种情况下,这不是一个问题,因为函数定义中创建的名称"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数据模型。

0