Python:惰性子模块导入使父模块无效>;取消绑定LocalError-但为什么?

Python:惰性子模块导入使父模块无效>;取消绑定LocalError-但为什么?,python,python-import,python-module,Python,Python Import,Python Module,考虑到以下准则: 我在我的代码中使用了一个子模块,在一个函数中使用了一个特殊的子模块(可能很难加载),所以我懒得导入: import xml.etree def y(): print(xml.etree.__name__) def x(): print(xml.etree.__name__) import xml.dom print(xml.dom.__name__) if __name__ == "__main__": y()

考虑到以下准则: 我在我的代码中使用了一个子模块,在一个函数中使用了一个特殊的子模块(可能很难加载),所以我懒得导入:

import xml.etree

def y():
    print(xml.etree.__name__)

def x():
    print(xml.etree.__name__)

    import xml.dom
    print(xml.dom.__name__)

if __name__ == "__main__":
    y()
    x()
这将导致
xml
被解除绑定:

UnboundLocalError: local variable 'xml' referenced before assignment
(是要修复它,我可以在函数中向上移动导入,或者从xml导入dom执行

我很想知道这里发生了什么。
显然,导入是在Python进入函数之前计算的


这背后的原因是什么?

导入在进入函数之前不会进行评估,但在执行之前会对函数体进行赋值分析。赋值中绑定的任何名称都被视为函数的本地名称,因为它是主体的开始。由于
import
是一种隐式赋值形式,因此名称
xml
只是函数的局部名称。但您是在
导入
分配之前使用它的。所以这个错误其实是很明显的

要解决此问题,您可以按您所说的做,或者只需使用
global

import xml.etree

def y():
    print(xml.etree.__name__)

def x():
    global xml
    print(xml.etree.__name__)

    import xml.dom
    print(xml.dom.__name__)

if __name__ == "__main__":
    y()
    x()

在一个更简单的示例中也是如此:

a=1
def foo():
印刷品(a)#作品
def bar():
打印(a)#出现错误
a=2
印刷品(a)
foo()
bar()
这使得:

1
UnboundLocalError: local variable 'a' referenced before assignment

原因是局部变量(如全局变量)是在编译时确定的,覆盖了同名的全局变量,但仅在运行时绑定到该值,因此如果在赋值之前访问它们,则它们是已知的,但尚未定义(例如绑定)。

问得好。您也可以通过使用
全局xml
来修复它,但我不完全确定这意味着什么。。。