Background is I'm getting data from a JSON API where lots of fields are optional and I want most of the fields in a database. When a specific field isn't available I want an empty string (""
) written into the database.
Currently I've been doing:
if jsonobject.what_i_look_for:
dbstring = jsonobject.what_i_look_for
else:
dbstring = ""
And then inserted dbstring into the database. However I'm getting a lot more of these fields now and I want a much cleaner code rather than a function which consists about 80% of if-statements.
I've found if-shorthands and this shorthand to check if a variable is empty, but both don't seem to work directly as a string. I've tested this using print()
in an interactive python 3.5.2 shell:
>>> print(testvar or "")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'testvar' is not defined
>>> print(testvar if testvar else "")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'testvar' is not defined
This: echo (isset($testvar) ? $testvar : "");
is the PHP equivalent of what I seek.
Edit: Since it seems relevant: The object I am trying to process is coming from Telegram's JSON API. I'm using python-telegram-bot
as library and this is an example object.
The Pythonic way is to look out for NameError
exception that would be raised when the variable is not defined, the name is not bound to any object to be precise.
So, for example:
try:
foobar
except NameError:
# Do stuffs
print('foobar is not defined')
raise # raise the original exception again, if you want
Names reside in namespaces e.g. local names reside in locals()
(dict
) namespace, global names reside in globals()
(dict
) namespace. You can define a function that takes name string and namespace as an argument to check for the existence, here is a hint passing namespace as a dict
and catching KeyError
:
In [1213]: def is_defined(name, namespace):
...: try:
...: namespace[name]
...: except KeyError:
...: return False
...: return True
...:
In [1214]: is_defined('spamegg', globals())
Out[1214]: False
In [1215]: spamegg = 10
In [1216]: is_defined('spamegg', globals())
Out[1216]: True
On the other hand, if you are looking to get the value of an atrribute string of an object, getattr
is the way to go:
getattr(obj, attr)
For example, the following two are equivalent:
obj.foobar
getattr(obj, 'foobar')
Even you can add a default when the object attribute is missing:
getattr(obj, 'foobar', 'spamegg')
The above will output the value obj.foobar
, if foobar
is missing it would output spamegg
.
You might also be interested in hasattr
that returns True
/False
for an attribute existence check, instead of needing to manually handle AttributeError
.
try
block for every variable I need to check doesn't exactly achieve that. — Aug 16, 2018 at 16:15 locals()
namespace, global names reside in globals()
namespace. You can define a function that takes namespace as an argument to check for the existence. — Aug 16, 2018 at 16:20 except NameError
is pretty major code smell to me, unless you are in to some pretty arcane meta-programming black-magic, maybe. In any event, reading the op it isn't clear to me if this is even what they need, since they are talking about attributes on objects. — Aug 16, 2018 at 16:20 External links referenced by this document: