سؤال

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 !

هل كانت مفيدة؟

المحلول

6.11. Conditional expressions

attr = myObject.someAttr if myObject else ""

نصائح أخرى

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top