About 5 years ago Martijn Faasen wrote the wonderful blog article What is Pythonic. One thing that I feel is extremely Pythonic is to not compare certain thing to other things when Python has built-in understanding of what false or true means.
Having reviewed/read a lot of beginner code or senior code but of people coming from lower-level languages I often see this:
if variable == False:
...
if variable == 0:
...
if variable == None:
...
if len(variable) == 0:
...
if variable == []:
...
if variable == {}:
...
if ORM.filter(user=variable).count == 0:
...
if not bool(variable):
...
To be Pythonic is to understand that Python evaluates all of these to false. All built in types have a perfectly sensible boolean operator which is automatically used in an if statement or an embedded if statement in a list comprehension. Keep it clean a pure just like this to check for true:
if not variable:
...
if not ORM.filter(user=variable):
...
And if you have your custom class such as the example just above with the pseudo "ORM" it's easy to extend it by writing your own custom __bool__
like this:
class MyCustomType(somebuiltintype):
...
def __bool__(self):
return self.somedate and self.somecondition
By playing along with Python just the way Guido indented it you can abstract yourself from being overly dependent of types. By doing the shorthand notation a variable that is otherwise a list can be None
if it's not set and your code will continue to work.
All the above might not be true for more explicit lower-level languages like C++ but it sure is Pythonic in Python and that's a good thing.
Comments
Post your own commenton the other hand, pythonic also means that "explicit is better than implicit" and sometimes you want to check that you have an empty list, not just that your variable evaluates to false. specifying the exact equality also often makes the code more readable as it provides an extra bit of information.
maybe __nonzero__ ?
If think it's important to stress that equality testing, truth testing and identity testing are all distinct operations each with different characteristics.
Thus:
if variable: #this is truth testing
if variable == 0: #this is equality testing
if variable is None: #this is identity testing
It's important to know what objects you're expecting to handle in your conditional statement, because different objects may behave in unusual ways. In fact, of these three operations, only identity testing is guaranteed safe. For example, try "if var ==0: ..." where var is a numpy array and it'll fail with an exception.
Sure, use equality or identity testing when it's applicable.
But how often is that? ...compared to how often it would be more appropriate and concise to use the shorthand?
Careful:
if variable == 0:
is equivalent to
if variable
only if you know for sure that variable is numeric. Suppose you have a variable that can be a number or None (a rather common occurrence, typically in case a of a numerical parameter that can be omitted)
if variable is None:
tests whether the variable received a number (or not),
if variable == 0.0:
tests something else altogether. In fact it really depends what you mean: if you want to test whether something evaluates to True, by all means use:
if variable:
But if you want to test whether a string is empty (but not None) just write it so.
It's still called __nonzero__ before python 3k isn't it..?