I'm trying to call a class member variable from within its class, but I get a NameError: name '...' is not defined.
A similar situation is created by means of the following minimum working example:
from pprint import pprint
class MyClass:
_my_class_variable = {'key_0': 0,
'key_1': 1}
_my_keys = _my_class_variable.keys()
pprint(_my_class_variable) # WORKS!
pprint([value for value in _my_class_variable.values()]) # WORKS!
pprint([_my_class_variable[key] for key in _my_keys]) # DOES NOT WORK!
pprint([_my_class_variable[key] for key in _my_class_variable.keys()]) # DOES NOT WORK!
which returns NameError: name '_my_class_variable' is not defined.
How is it possible that the first two pprint command work but not the last two pprint commands?
Everything in the list comprehension is run in a separate scope (as a function, basically), except for the iterable used for the loop. So, on the lines that don't work, _my_class_variable is not defined.
One way to solve this would be to make sure that you pass _my_class_variable to an immediately executing lambda function so that it's available in the list comprehension's scope :
pprint((lambda _my_class_variable : [_my_class_variable[key] for key in _my_class_variable.keys()])(_my_class_variable)) # DOES WORK!
# or
pprint((lambda _my_class_variable=_my_class_variable : [_my_class_variable[key] for key in _my_class_variable.keys()])()) # DOES WORK!
Why does this work? List comprehensions get their own separate scope in Python 3 and are wrapped in a temporary function object and called immediately. If you were to create an explicit scope for the _my_class_variable, like in a function, its scope will be considered when resolving _my_class_variable.
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