This question already has answers here: Easy way to check that a variable is defined in python? [duplicate] (5 answers) Closed 2 years ago.
How do you know whether a variable has been set at a particular place in the code at runtime? This is not always obvious because (1) the variable could be conditionally set, and (2) the variable could be conditionally deleted. I'm looking for something like defined()
in Perl or isset()
in PHP or defined?
in Ruby.
if condition:
a = 42
# is "a" defined here?
if other_condition:
del a
# is "a" defined here?
import
to "source" a "config file" (i.e. a file that only has assignments in it), it may very well be that some variable has not been defined there. And import
is sure cheaper/simpler than ConfigParser
, so for me pragmatism wins over beauty here.
try:
thevariable
except NameError:
print("well, it WASN'T defined after all!")
else:
print("sure, it was defined.")
'a' in vars() or 'a' in globals()
if you want to be pedantic, you can check the builtins too
'a' in vars(__builtins__)
if "prop2" in {"prop0": None, "prop1": None}:
vars(__builtin__)
still works (either for Python 2 or 3). I believe vars(__builtins__)
(mind the plural ;-)) should be used for both versions now (tested on: Python 2.7.10 and Python 3.6.1).
globals()
is a superset of locals()
.
I think it's better to avoid the situation. It's cleaner and clearer to write:
a = None
if condition:
a = 42
a
to None
ie. UNDEFINED=object();a=UNDEFINED
then you can test with a is not UNDEFINED
null
value as different from an unspecified value (eg. None
sets the actual JSON value to null
, whereas an unspecified leaves it out of the JSON message entirely, which makes the API use a default or calculate from other attributes), you need to either differentiate None
from Undefined
, or None
from JSON null
. It's incredibly short-sighted to think that None
can't or shouldn't ever be used as distinct from a value that is explicitly unspecified or undefined.
try:
a # does a exist in the current namespace
except NameError:
a = 10 # nope
if 'a' in vars() or 'a' in globals()
solution mentioned above, which does not require an exception
For this particular case it's better to do a = None
instead of del a
. This will decrement reference count to object a
was (if any) assigned to and won't fail when a
is not defined. Note, that del
statement doesn't call destructor of an object directly, but unbind it from variable. Destructor of object is called when reference count became zero.
One possible situation where this might be needed:
If you are using finally
block to close connections but in the try
block, the program exits with sys.exit()
before the connection is defined. In this case, the finally
block will be called and the connection closing statement will fail since no connection was created.
Success story sharing
StopIteration
within just about everyfor
statement -- that's how an iterator lets it known that it's all done. And of course, it is far from "an exceptional case" for iteration to be done -- indeed, one expects most iterations to terminate. Thus, obviously, your opinions on how exceptions "should" be used are not correctly applicable to Python (other languages have different pragmatics and the question cannot be properly treated as "language agnostic" as in the Q you point to).