Considering the following code: I'm using a submodule allover my code and a special submodule (might be uber heavy to load) in only one function so I'm lazy importing:
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()
This will result in xml
being unbound:
UnboundLocalError: local variable 'xml' referenced before assignment
(yes to fix it I can move the import up within the function OR do from xml import dom
)
I'd love to know what happens here.
Apparently the imports are evaluated just before Python is entering the function.
What's the reasoning behind this?
Imports are not evaluated before entering the function, but the function body is parsed for assignments before execution. Any name bound in an assignment is considered a name local to the function, since the beginning of the body. As an import
is an implicit form of assignment, the name xml
just becomes local to the function. But you are using it before the import
assignment. So the error is actually quite obvious.
To fix it you can do as you say or simply use 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()