attr = myObject.someAttr if myObject else ""
Short way to write if exists else
-
01-07-2023 - |
Question
What I want to do is :
if myObject: # (not None)
attr = myObject.someAttr
else:
attr = ''
And avoiding if possible, ternary expressions. Is there something like :
attr = myObject.someAttr || '' ?
I was thinking of creating my own function such as :
get_attr_or_default(instance,attr,default):
if instance:
return instance.get_attribute(attr)
else:
return default
But I would be surprised to hear that python doesn't have a shortcut for this.
Synthesis :
I tried both of solutions and here's the result :
class myClass(Models.model):
myObject = model.foreignKey('AnotherClass')
class AnotherClass(Models.model):
attribute = models.charField(max_length=100,default = '')
attr = myClass.myObject.attribute if myClass.myObject else '' # WORKED
attr = myClass.myObject and myClass.myObject.attribute # WORKED with NONE as result
attr = myClass.myObject.attribute or '' # Raises an error (myObject doesn't have attribute attribute)
try: attr = myClass.myObject.attribute
except AttributeError: attr = '' # Worked
Thanks for your answers !
Solution
OTHER TIPS
This will set attr
to None
if myObject
is None
and someAttr
if it a proper object.
attr = myObject and myObject.someAttr
The evaluation on the right-hand side is only performed if required for the value, see Python Docs, which say:
In the case of and, if the left-hand side is equivalent to False, the right-hand side is not evaluated, and the left-hand value is returned.
This is the same pattern as the ??
null-coalsecing operator that C# has, see http://msdn.microsoft.com/en-us/library/ms173224.aspx.
Note that this will not work well if you have a boolean operator on your object. If so, you need to use myObject is not None
.
Cool way (even w/out ternary expressions):
attr = getattr(myObject or object(), 'someAttr', '')
object()
returns a new featureless object (quoting the documentation).
myObject or object()
will return object()
if myObject
is empty.
Logic:
myObject is empty?
/ \
/ \ N
/ \
Y / getattr(myObject, ...) returns that attribute
/
/
/
getattr(object(), ...) will produce '' (empty string)
At best you can do:
try:
attr = myObject.someAttr
except AttributeError:
attr = ''
If you really insist on doing things in strange, convoluted and tricky way, you could try:
val = (myObject is not None and myObject.attr) or default
which is the old (and quite controversial) pre-ternary-expression idiom. Note that this will NOT work as expected if bool(myObject.attr)
evals to False
(which will be the case for most empty containers, empty strings, numeric zeros and quite a few non-builtin types).
TL;DR : use the ternary expression, that's what it's for.
What you suggested yourself, but slightly different:
if myObject:
attr = myObject.someAttr or ''
If myObject.someAttr
is None
it will ignore it and put ''
in attr