How do I check if a variable exists?
Question:
I want to check if a variable exists. Now I’m doing something like this:
try:
myVar
except NameError:
# Do something.
Are there other ways without exceptions?
Answers:
catch
is called except
in Python. other than that it’s fine for such simple cases. There’s the AttributeError
that can be used to check if an object has an attribute.
To check the existence of a local variable:
if 'myVar' in locals():
# myVar exists.
To check the existence of a global variable:
if 'myVar' in globals():
# myVar exists.
To check if an object has an attribute:
if hasattr(obj, 'attr_name'):
# obj.attr_name exists.
The use of variables that have yet to been defined or set (implicitly or explicitly) is often a bad thing in any language, since it tends to indicate that the logic of the program hasn’t been thought through properly, and is likely to result in unpredictable behaviour.
If you need to do it in Python, the following trick, which is similar to yours, will ensure that a variable has some value before use:
try:
myVar
except NameError:
myVar = None # or some other default value.
# Now you're free to use myVar without Python complaining.
However, I’m still not convinced that’s a good idea – in my opinion, you should try to refactor your code so that this situation does not occur.
By way of an example, the following code was given below in a comment, to allow line drawing from a previous point to the current point:
if last:
draw(last, current);
last = current
In the case where last
has not been bound to a value, that won’t help in Python at all since even the checking of last
will raise an exception. A better idea would be to ensure last
does have a value, one that can be used to decide whether or not it is valid. That would be something like:
last = None
# some time passes ...
if last is not None:
draw(last, current);
last = current
That ensures the variable exists and that you only use it if it’s valid for what you need it for. This is what I assume the if last
was meant to do in the comment code (but didn’t), and you can still add the code to force this if you have no control over the initial setting of the variable, using the exception method above:
# Variable 'last' may or may not be bound to a value at this point.
try:
last
except NameError:
last = None
# It will always now be bound to a value at this point.
if last is not None:
draw(last, current);
last = current
Using try/except is the best way to test for a variable’s existence. But there’s almost certainly a better way of doing whatever it is you’re doing than setting/testing global variables.
For example, if you want to initialize a module-level variable the first time you call some function, you’re better off with code something like this:
my_variable = None
def InitMyVariable():
global my_variable
if my_variable is None:
my_variable = ...
A way that often works well for handling this kind of situation is to not explicitly check if the variable exists but just go ahead and wrap the first usage of the possibly non-existing variable in a try/except NameError:
# Search for entry.
for x in y:
if x == 3:
found = x
# Work with found entry.
try:
print('Found: {0}'.format(found))
except NameError:
print('Not found')
else:
# Handle rest of Found case here
...
I will assume that the test is going to be used in a function, similar to user97370’s answer. I don’t like that answer because it pollutes the global namespace. One way to fix it is to use a class instead:
class InitMyVariable(object):
my_variable = None
def __call__(self):
if self.my_variable is None:
self.my_variable = ...
I don’t like this, because it complicates the code and opens up questions such as, should this confirm to the Singleton programming pattern? Fortunately, Python has allowed functions to have attributes for a while, which gives us this simple solution:
def InitMyVariable():
if InitMyVariable.my_variable is None:
InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None
for objects/modules, you can also
'var' in dir(obj)
For example,
>>> class Something(object):
... pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False
A simple way is to initialize it at first saying myVar = None
Then later on:
if myVar is not None:
# Do something
I created a custom function.
def exists(var):
return var in globals()
Then the call the function like follows replacing variable_name
with the variable you want to check:
exists("variable_name")
Will return True
or False
Short variant:
my_var = some_value if 'my_var' not in globals() else my_var:
This was my scenario:
for i in generate_numbers():
do_something(i)
# Use the last i.
I can’t easily determine the length of the iterable, and that means that i
may or may not exist depending on whether the iterable produces an empty sequence.
If I want to use the last i
of the iterable (an i
that doesn’t exist for an empty sequence) I can do one of two things:
i = None # Declare the variable.
for i in generate_numbers():
do_something(i)
use_last(i)
or
for i in generate_numbers():
do_something(i)
try:
use_last(i)
except UnboundLocalError:
pass # i didn’t exist because sequence was empty.
The first solution may be problematic because I can’t tell (depending on the sequence values) whether i
was the last element. The second solution is more accurate in that respect.
Like so:
def no(var):
"give var as a string (quote it like 'var')"
assert(var not in vars())
assert(var not in globals())
assert(var not in vars(__builtins__))
import keyword
assert(var not in keyword.kwlist)
Then later:
no('foo')
foo = ....
If your new variable foo
is not safe to use, you’ll get an AssertionError
exception which will point to the line that failed, and then you will know better.
Here is the obvious contrived self-reference:
no('no')
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-88-d14ecc6b025a> in <module>
----> 1 no('no')
<ipython-input-86-888a9df72be0> in no(var)
2 "give var as a string (quote it)"
3 assert( var not in vars())
----> 4 assert( var not in globals())
5 assert( var not in vars(__builtins__))
6 import keyword
AssertionError:
Also a possibility for objects, use __dict__
.
class A(object):
def __init__(self):
self.m = 1
a = A()
assert "m" in a.__dict__
assert "k" not in a.__dict__
It may not be performant, but you generalise the solution to a function that checks both local variables and global variables.
import inspect
def exists_var(var_name):
frame = inspect.currentframe()
try:
return var_name in frame.f_back.f_locals or var_name in globals()
finally:
del frame
Then you can use it like this:
exists_var('myVar')
I want to check if a variable exists. Now I’m doing something like this:
try:
myVar
except NameError:
# Do something.
Are there other ways without exceptions?
catch
is called except
in Python. other than that it’s fine for such simple cases. There’s the AttributeError
that can be used to check if an object has an attribute.
To check the existence of a local variable:
if 'myVar' in locals():
# myVar exists.
To check the existence of a global variable:
if 'myVar' in globals():
# myVar exists.
To check if an object has an attribute:
if hasattr(obj, 'attr_name'):
# obj.attr_name exists.
The use of variables that have yet to been defined or set (implicitly or explicitly) is often a bad thing in any language, since it tends to indicate that the logic of the program hasn’t been thought through properly, and is likely to result in unpredictable behaviour.
If you need to do it in Python, the following trick, which is similar to yours, will ensure that a variable has some value before use:
try:
myVar
except NameError:
myVar = None # or some other default value.
# Now you're free to use myVar without Python complaining.
However, I’m still not convinced that’s a good idea – in my opinion, you should try to refactor your code so that this situation does not occur.
By way of an example, the following code was given below in a comment, to allow line drawing from a previous point to the current point:
if last:
draw(last, current);
last = current
In the case where last
has not been bound to a value, that won’t help in Python at all since even the checking of last
will raise an exception. A better idea would be to ensure last
does have a value, one that can be used to decide whether or not it is valid. That would be something like:
last = None
# some time passes ...
if last is not None:
draw(last, current);
last = current
That ensures the variable exists and that you only use it if it’s valid for what you need it for. This is what I assume the if last
was meant to do in the comment code (but didn’t), and you can still add the code to force this if you have no control over the initial setting of the variable, using the exception method above:
# Variable 'last' may or may not be bound to a value at this point.
try:
last
except NameError:
last = None
# It will always now be bound to a value at this point.
if last is not None:
draw(last, current);
last = current
Using try/except is the best way to test for a variable’s existence. But there’s almost certainly a better way of doing whatever it is you’re doing than setting/testing global variables.
For example, if you want to initialize a module-level variable the first time you call some function, you’re better off with code something like this:
my_variable = None
def InitMyVariable():
global my_variable
if my_variable is None:
my_variable = ...
A way that often works well for handling this kind of situation is to not explicitly check if the variable exists but just go ahead and wrap the first usage of the possibly non-existing variable in a try/except NameError:
# Search for entry.
for x in y:
if x == 3:
found = x
# Work with found entry.
try:
print('Found: {0}'.format(found))
except NameError:
print('Not found')
else:
# Handle rest of Found case here
...
I will assume that the test is going to be used in a function, similar to user97370’s answer. I don’t like that answer because it pollutes the global namespace. One way to fix it is to use a class instead:
class InitMyVariable(object):
my_variable = None
def __call__(self):
if self.my_variable is None:
self.my_variable = ...
I don’t like this, because it complicates the code and opens up questions such as, should this confirm to the Singleton programming pattern? Fortunately, Python has allowed functions to have attributes for a while, which gives us this simple solution:
def InitMyVariable():
if InitMyVariable.my_variable is None:
InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None
for objects/modules, you can also
'var' in dir(obj)
For example,
>>> class Something(object):
... pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False
A simple way is to initialize it at first saying myVar = None
Then later on:
if myVar is not None:
# Do something
I created a custom function.
def exists(var):
return var in globals()
Then the call the function like follows replacing variable_name
with the variable you want to check:
exists("variable_name")
Will return True
or False
Short variant:
my_var = some_value if 'my_var' not in globals() else my_var:
This was my scenario:
for i in generate_numbers():
do_something(i)
# Use the last i.
I can’t easily determine the length of the iterable, and that means that i
may or may not exist depending on whether the iterable produces an empty sequence.
If I want to use the last i
of the iterable (an i
that doesn’t exist for an empty sequence) I can do one of two things:
i = None # Declare the variable.
for i in generate_numbers():
do_something(i)
use_last(i)
or
for i in generate_numbers():
do_something(i)
try:
use_last(i)
except UnboundLocalError:
pass # i didn’t exist because sequence was empty.
The first solution may be problematic because I can’t tell (depending on the sequence values) whether i
was the last element. The second solution is more accurate in that respect.
Like so:
def no(var):
"give var as a string (quote it like 'var')"
assert(var not in vars())
assert(var not in globals())
assert(var not in vars(__builtins__))
import keyword
assert(var not in keyword.kwlist)
Then later:
no('foo')
foo = ....
If your new variable foo
is not safe to use, you’ll get an AssertionError
exception which will point to the line that failed, and then you will know better.
Here is the obvious contrived self-reference:
no('no')
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-88-d14ecc6b025a> in <module>
----> 1 no('no')
<ipython-input-86-888a9df72be0> in no(var)
2 "give var as a string (quote it)"
3 assert( var not in vars())
----> 4 assert( var not in globals())
5 assert( var not in vars(__builtins__))
6 import keyword
AssertionError:
Also a possibility for objects, use __dict__
.
class A(object):
def __init__(self):
self.m = 1
a = A()
assert "m" in a.__dict__
assert "k" not in a.__dict__
It may not be performant, but you generalise the solution to a function that checks both local variables and global variables.
import inspect
def exists_var(var_name):
frame = inspect.currentframe()
try:
return var_name in frame.f_back.f_locals or var_name in globals()
finally:
del frame
Then you can use it like this:
exists_var('myVar')