Is it safe to rely on condition evaluation order in if statements?

Viewed 34231

Is it bad practice to use the following format when my_var can be None?

if my_var and 'something' in my_var:
    #do something

The issue is that 'something' in my_var will throw a TypeError if my_var is None.

Or should I use:

if my_var:
    if 'something' in my_var:
        #do something

or

try:
    if 'something' in my_var:
        #do something
except TypeError:
    pass

To rephrase the question, which of the above is the best practice in Python (if any)?

Alternatives are welcome!

6 Answers

It's safe to depend on the order of conditionals (Python reference here), specifically because of the problem you point out - it's very useful to be able to short-circuit evaluation that could cause problems in a string of conditionals.

This sort of code pops up in most languages:

IF exists(variable) AND variable.doSomething()
    THEN ...

Yes it is safe, it's explicitly and very clearly defined in the language reference:

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

It's not that simple. As a C# dude I am very used to doing something like:

if(x != null && ! string.isnullorempty(x.Name))
{
   //do something
}

The above works great and is evaluated as expected. However in VB.Net the following would produce a result you were NOT expecting:

If Not x Is Nothing **And** Not String.IsNullOrEmpty(x.Name) Then

   'do something

End If

The above will generate an exception. The correct syntax should be

If Not x Is Nothing **AndAlso** Not String.IsNullOrEmpty(x.Name) Then

   'do something

End If

Note the very subtle difference. This had me confused for about 10 minutes (way too long) and is why C# (and other) dudes needs to be very careful when coding in other languages.

I would go with the try/except, but it depends on what you know about the variable.

If you are expecting that the variable will exist most of the time, then a try/except is less operations. If you are expecting the variable to be None most of the time, then an IF statement will be less operations.

It's perfectly safe and I do it all the time.

Related