Consider the snippet
import something
import sys
print(sys.version)
def f(a):
b = a
if a==1:
import something
b *= something.value # <<<<<
return b
print(f(1))
print(f(2))
where the module something
defines value = 1
. Running that script with Python 3.6.7, the call f(1)
succeeds but the call f(2)
fails with an exception:
UnboundLocalError: local variable 'something' referenced before assignment
at the line marked with <<<<<
. I really don't understand that. I found the same issue with Python 2.7, so I would bet this is not a simple regression but really tied to the way Python handles such local imports. I could not find any hint in the documentation. Has anybody an explanation?
An import x
statement does two things*
Your function only assigns the module something
to the variable something
when a == 1
. If a != 1
, even if the module has been loaded, it is not assigned to a variable, so cannot be referenced.
This is why what you're doing fails. It's also why what you're trying to do provides you with absolutely no advantage because modules are only loaded and run the first time they are imported. Every subsequent time is just doing step 2.
The reason your code is not referencing the global something
is because python overrides global names if a local variable of the same name appears anywhere in a function, even if it is never reached. The following function f
fails similar to how yours does.
x = 1
def f(y):
if False:
x = y
return x
The solution is to not use x
as both a local and global variable.
If there is a assignment to a variable in a given scope, the variable is local to that scope. If that assignment is conditional and you can run your code such as it never happens (or it is referenced in that scope after being assigned to), you get this very exception. Smaller example of the same:
def f():
if False:
a = 1
print(a)
a = 1
f()
And the obligatory FAQ link.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With