Reputation: 13748
After I write below code:
if isinstance(lst, (list, tuple)) and len(lst) > 0:
lst = [v.lower() for v in lst]
pv_on, uv_on = 'pv'in lst, 'uv' in lst
ouput error in PyCharm: NameError: name 'lst' is not defined
But if I use lst2
instead 'lst' inside [v.lower() for v in lst]
as follow, it works fine.I just want to know why.
if isinstance(lst, (list, tuple)) and len(lst) > 0:
lst2 = [v.lower() for v in lst]
pv_on, uv_on = 'pv'in lst2, 'uv' in lst2
Update:
Maybe caused by decorator,
test code:
lst = ['A', 'B', 'C']
def record_deco(lst):
def _wrapper(func):
def wrapper(*args,**kwargs):
if isinstance(lst, (list, tuple)) and len(lst) > 0:
lst = [v.lower() for v in lst]
a_on, b_on = 'a' in lst, 'b' in lst
print a_on
print b_on
return func(*args, **kwargs)
return wrapper
return _wrapper
@record_deco(['a'])
def a(x):
print x
a('xxx')
This time I use sublime,the ouput error is :UnboundLocalError: local variable 'lst' referenced before assignment
And this error disappear after I change lst
to lst2
.
Upvotes: 0
Views: 801
Reputation: 251383
If you assign to a variable anywhere in a function, Python treats all uses of that variable in the function as local variables. Since you assign to lst
in wrapper
it is treated as local to wrapper
. That means that when you do lst = [v.lower() for v in lst]
, the local variable lst
already needs to exist so it can be iterated over. But no local variable lst
exists, so an error is raised. You can find dozens of other questions about this by searching Stackoverflow for UnboundLocalError.
The solution, as you already found, is to use a different name for your inner variable. (In Python 3 you could use nonlocal lst
to mark lst
as being used from the enclosing record_deco
function, but that wouldn't accomplish anything special here since you don't use lst
except in the nested function.)
Upvotes: 2
Reputation: 6365
lst = ['A', 'B', 'C']
lst = [v.lower() for v in lst]
a_on, b_on = 'a' in lst, 'b' in lst
a_on, b_on
(True, True)
Works for me. Puzzling.
Upvotes: 2