In /tmp/spam.py:
n = 69
if n == True:
print 'potato'
pep8 utility complains about this conditional:
wim#SDFA100461C:/tmp$ pep8 spam.py
spam.py:3:6: E712 comparison to True should be 'if cond is True:' or 'if cond:'
the first suggestion is wrong/"worse" according to pep8 itself
the second suggestion changes the behaviour of the code
What is the best practice for a case where you actually do want to check equality with True? Is identity checking with True using is OK? Why does pep8 utility offer an alternative which is explicitly discouraged in pep8 itself?
If you really do need to check equality with True then use == and ignore PEP8, but in almost any conceivable case that isn't what you want.
If you want to know whether the value you have is one of the values Python considers to be true, use if cond:. If you want to know whether the value you have is the singleton value True then use is True, the booleans True and False are singletons so it is correct to use is in this situation.
If you need to test whether your object is the singleton True, but a linter or a code reviewer complains about is True, then isinstance(x, bool) and x is a behaviorally equivalent (but slower) substitute.
Checking x == True is a halfway house. It is true when x is True is true, and false for your case of x=69, but there are other objects which are not themselves True but for which x==True gives an unexpectedly true result such as 1 == True being true. (thanks #Ant).
So putting that together:
value of n: True 1 69 False 0
-----------------------------------------------
expression result
-----------------------------------------------
if n: True True True False False
if n is True: True False False False False
if n==True: True True False False False
Pick the row from that table which gives the results you really wanted (and the last one isn't it).
Whatever you do, I think a comment is required since the code looks funny.
If you want to check equality with True then it might be clearer to write if n == 1. Someone reading the code is less likely to misinterpret it as an attempt to test logical truth.
Of course if n has a user-defined type it's possible to define n.__eq__ such that (n == True) != (n == 1), but it would be pretty nasty. So you'd have to decide whether the subtle difference in meaning is justified by the benefit of avoiding the code looking like an incorrect logical truth test.
If the difference is not justified, and if you're absolutely required to write to the PEP8 style guide, then either use assertEqual or write expected_value = True, if n == expected_value.
If the code is a unit test for an API that for some reason defines specifically that the literal True is returned, then of course you should test if n is True, not if n == True. As before, a comment or some indirection would be needed to stop the code looking wrong.
Another option is to change the API you're testing. The reason for the style guide rules is in part to discourage people from inventing or relying on APIs that specifically define that the return value must be identical or equal to the literal True, and instead define APIs and write their code in terms of logical truth. So if you "fix" the API you can "fix" the code that tests it.
Why do you need to explicitly test for True values? You rarely, if ever do need narrow your test down to a specific type. I'd rethink your use case here; if you are building an API that'll return a bool instead of in int for out-of-band conditions, then use exceptions instead.
If you do have to test for True only, then use
if n is True:
because the boolean values are meant to be singletons like None. See the Programming recommendations section:
Comparisons to singletons like None should always be done with is or is not, never the equality operators.
Moreover, because issubtype(bool, int) is true (for historical reasons; bool was introduced rather late in Python), n == True is also true for n = 1, if you can only accept True here then you can only use is True. You could also use isinstance(n, bool) and n, which would allow for subclasses of bool, but I cannot imagine there ever be a use for such a type, and in current implementations, bool explicitly prohibits being subclassed.
The PEP 8 rule about using not using if cond is True: is specifically called out because it limits the value of cond to the bool only.
Last but not least, PEP 8 starts with this:
A Foolish Consistency is the Hobgoblin of Little Minds
[...] But most importantly: know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best.
Only follow PEP 8 if it suits your needs.
The second recommendation would best suit your needs. The conditional statement if cond: will return true if the condition itself is true. It will not change the behavior of the code, as it is just shorthand for if cond == True:.
Related
Here is simple ST plugin. Is there a difference between commented lines? Personally, I don't see any difference in how they work, just a difference in visual appearance.
However, some plugin developers prefer second version (== 1), which looks just useless and ugly for me. Probably there are some reasons to prefer it?
import sublime_plugin
class ExpandUnexpandTabsCommand(sublime_plugin.EventListener):
def on_pre_save(self, view):
# if view.settings().get("translate_tabs_to_spaces"):
# if view.settings().get("translate_tabs_to_spaces") == 1:
# if view.settings().get("translate_tabs_to_spaces") == True:
view.run_command("expand_tabs")
else:
view.run_command("unexpand_tabs")
This is covered in PEP8, the official Python style guide's, "Programming Recommendations" section:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
In other parts of the guide, they emphasize this for other use cases (e.g. testing for empty/non-empty collections should not use len()); unless a specific value is critical to your logic, use the implicit boolean nature of what you're testing (with not if it must be inverted), don't spin your wheels with comparisons that ultimately add little in terms of readability, increase fragility, and slow your code to boot.
The only reason to prefer the other approaches is if you expect there to be other truthy values that should not count as truthy. In this case, the translate_tabs_to_spaces setting is very clearly boolean in nature, so you almost certainly want to handle any truthy value the same way; if they later redesigned the setting to have a numeric value, where 0 meant "don't translate" and any positive value meant the number of spaces each tab was worth, implicit truthiness evaluation would continue to work, but for the standard four space indents, a test for == 1 or == True would suddenly decide no translation was occurring.
It depends on what the possible values are.
If the file must have 0 or 1 in it, anything else is an error, and you're reading it as an int, then you probably want == 1.
If the file can have either True or no entry at all, and you're using get(…) instead of [] so you get back None whenever it's not True, then you want to just test the truthiness. (Or maybe is not None, but definitely not == True or == 1.)
The rule is pretty simple: when writing a test, write what you mean to test.
Different tests mean different things:
if spam:: passes if spam is anything truthy. That means anything besides None, False, numeric zero, or empty containers.
if spam == 1:: passes if spam is the number 1.
if spam is True:: passes only if spam is the special constant True. If you want to make sure other truthy values fail, and only True counts, use is. You rarely want this.
if spam == True:: passes if spam is the special constant True, or some object equal to it. If you've gone out of your way to write a class whose __eq__ tests for True or something, then you might want this test, but it's hard to imagine why you would otherwise.
It happens to be true that 1 == True. But writing == True when you want to test for the number 1, or == 1 when you want to test for True but not other truthy values, is misleading to anyone who understands idiomatic Python, and mildly confusing to anyone who doesn't, and there's no benefit to anyone. So don't do it.
And writing either of those when you want to test for anything truthy isn't just misleading, it's wrong.
if view.settings().get("translate_tabs_to_spaces") is more concise and readable. There is little if ever any need to compare a Boolean to another Boolean value, and using integers of 0 and 1 to denote a Boolean value should only be considered when the programming language does not support Boolean values.
The question I'm about to ask here has been asked before, but those questions/answers make no mention of what I want to know.
I recall a few months or so ago, I had a rather sizable Python script, and I was using if x: because it was shorter and I was lazy. I don't remember which version of Python, but I do remember getting a DeprecationWarning (or PendingDeprecationWarning?) about implicit comparisons to True.
Now, I'm trying to write something someone else might read. I'm using if x == True and if x is not None everywhere, and pep8 and pylint are complaining about this, saying I should use if x:.
Personally, I think if x: is far less readable, but pep8 (the program) and PEP 8 (the document) both disagree.
Google is not being very helpful in allowing me to figure in which version, if ever, Python gave a DeprecationWarning for if x:, so I wonder if perhaps the SO community can provide insight.
Should I be worrying about this at all? Does it actually matter that much?
The correct answer as to what condition to use is, in the first place, a matter of semantics rather than style. Unless x is a boolean value, 0/False or 1/True, which your question did not specify, if x: and if x == True: are semantically different conditions and often give different results. You should use whichever is the correct one for the situation. if x: is usually the correct choice, but not always. If x is specified (known) to be a boolean, then adding == True is superfluous and a waste of time for the writer, reader, and interpreter.
Under the covers, if x: means (is implemented as) if bool(x) is True in the normal meaning of this expression, and if x == True: means if bool(x == True) is True. Since x == True return a bool and bool(a_bool) is a_bool, the latter reduces to if (x == True) is True. In general, bool(x) is not the same as x == True.
if x is None: (or not None) should be used if and only if that is the proper condition. It often correct when testing the output of a function returns either an int (or string or ...) or None. In many other situations, it is usually wrong.
It is perfectly good Python, and Python 3.+ versions don't give a warning, so if you're writing code for other people to work with in the future, using if x: is perfectly fine. And by the way, on behalf of every developer who had to maintain horribly unreadable code, THANK YOU for considering the readability of your code.
I think you have several separate issues confused.
It's best to check what the style guide actually says, and double check how your code actually behaves, rather than relying only on remembered behaviour :-)
Boolean expressions are already either true or false
The expression in an if statement is always intepreted as boolean; anyone reading Python code needs to know that anyway.
So the following all mean exactly the same thing, and piling on == True does not improve readability:
if x + y:
…
if (x + y) == True:
…
if ((x + y) == True) == True:
…
if (((x + y) == True) == True) == True:
…
which is why PEP 8 says:
Don't compare boolean values to True or False using == .
Singletons should be compared using identity
The comparison of an object to None implies that value is treated specially; it is commonly used as a sentinel for special processing. It is a singleton, so comparing whether an object is merely equal to None is ambiguous.
So, if your intent is to test a value for None, you should test whether the object is none by testing its identity:
if x is None:
…
if x is not None:
…
which is why PEP 8 says:
Comparisons to singletons like None should always be done with is or is not , never the equality operators.
None is not the only value that is boolean false
There are many values which are false in a boolean context, so doing a mere if x: is not enough to tell whether an object is actually None.
Which is why PEP 8 says:
beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value.
I know that Python guarantees that there is only one instance of NoneType, the None object, so that you can safely use is None to test if something equals None.
Is there an equivalent guarantee for bool True and False (i.e. that there is only one instance of each)?
If not, why not?
EDIT: In particular, I've noticed that (n+0) is (0+n) gives True for n in range(-5, 257) and False otherwise. In other words, zero, the first 256 positive and the first 5 negative integers seem to be pre-cached and are not instanced again. I am guessing that that's a choice of the interpreter (CPython, in my case) and not a specification of the language. And bool derives from int, so I still have to wonder about what expectations I can have with other interpreters.
EDIT: To clarify, since this seems to have generated a lot of confusion, my intention is not to test the boolean interpretation of a value. For that I would never use is True or is False. My intention is to be able to tell apart False from everything else, in a variable that can have values of several types including empty strings, zeros, and None, and similarly for True. I'm myself an experienced programmer, of the kind who cringes when I see "if booleanvar == True".
NOTE ON DUPLICATES: The questions this one was alleged to be a duplicate of (this and this) don't answer this question; they merely state that bool is a subclass of int that differ mainly in their repr, not if True and False are guaranteed to be unique.
Also, note that it's not a question about what the names True and False are bound to, but about the instances of the class bool.
From the docs (https://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy):
Booleans
These represent the truth values False and True. The two objects representing the values False and True are the only Boolean objects.
There are only two objects, any computation producing a boolean will produce one of those two existing objects:
>>> (1 == 1) is True
True
>>> (1 == 0) is False
True
The bool type has only two instances, True and False. Furthermore, it can't be subclassed, so there's no way to create a derived class that can have additional instances.
But even though it's guaranteed, there's seldom a good reason to rely upon it. You should usually use if x rather than if x is True, and avoid situations where you need to distinguish True from other truthy values or False from other falsy values.
I ran into unexpected results in a python if clause today:
import numpy
if numpy.allclose(6.0, 6.1, rtol=0, atol=0.5):
print 'close enough' # works as expected (prints message)
if numpy.allclose(6.0, 6.1, rtol=0, atol=0.5) is True:
print 'close enough' # does NOT work as expected (prints nothing)
After some poking around (i.e., this question, and in particular this answer), I understand the cause: the type returned by numpy.allclose() is numpy.bool_ rather than plain old bool, and apparently if foo = numpy.bool_(1), then if foo will evaluate to True while if foo is True will evaluate to False. This appears to be the work of the is operator.
My questions are: why does numpy have its own boolean type, and what is best practice in light of this situation? I can get away with writing if foo: to get expected behavior in the example above, but I like the more stringent if foo is True: because it excludes things like 2 and [2] from returning True, and sometimes the explicit type check is desirable.
You're doing something which is considered an anti-pattern. Quoting PEP 8:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
The fact that numpy wasn't designed to facilitate your non-pythonic code isn't a bug in numpy. In fact, it's a perfect example of why your personal idiom is an anti-pattern.
As PEP 8 says, using is True is even worse than == True. Why? Because you're checking object identity: not only must the result be truthy in a boolean context (which is usually all you need), and equal to the boolean True value, it has to actually be the constant True. It's hard to imagine any situation in which this is what you want.
And you specifically don't want it here:
>>> np.True_ == True
True
>>> np.True_ is True
False
So, all you're doing is explicitly making your code incompatible with numpy, and various other C extension libraries (conceivably a pure-Python library could return a custom value that's equal to True, but I don't know of any that do so).
In your particular case, there is no reason to exclude 2 and [2]. If you read the docs for numpy.allclose, it clearly isn't going to return them. But consider some other function, like many of those in the standard library that just say they evaluate to true or to false. That means they're explicitly allowed to return one of their truthy arguments, and often will do so. Why would you want to consider that false?
Finally, why would numpy, or any other C extension library, define such bool-compatible-but-not-bool types?
In general, it's because they're wrapping a C int or a C++ bool or some other such type. In numpy's case, it's wrapping a value that may be stored in a fastest-machine-word type or a single byte (maybe even a single bit in some cases) as appropriate for performance, and your code doesn't have to care which, because all representations look the same, including being truthy and equal to the True constant.
why does numpy have its own boolean type
Space and speed. Numpy stores things in compact arrays; if it can fit a boolean into a single byte it'll try. You can't easily do this with Python objects, as you have to store references which slows calculations down significantly.
I can get away with writing if foo: to get expected behavior in the example above, but I like the more stringent if foo is True: because it excludes things like 2 and [2] from returning True, and sometimes the explicit type check is desirable.
Well, don't do that.
First, the code:
>>> False or 'hello'
'hello'
This surprising behavior lets you check if x is not None and check the value of x in one line:
>>> x = 10 if randint(0,2) == 1 else None
>>> (x or 0) > 0
# depend on x value...
Explanation: or functions like this:
if x is false, then y, else x
No language that I know lets you do this. So, why does Python?
It sounds like you're combining two issues into one.
First, there's the issue of short-circuiting. Marcin's answer addresses this issue perfectly, so I won't try to do any better.
Second, there's or and and returning the last-evaluated value, rather than converting it to bool. There are arguments to be made both ways, and you can find many languages on either side of the divide.
Returning the last-evaluated value allows the functionCall(x) or defaultValue shortcut, avoids a possibly wasteful conversion (why convert an int 2 into a bool 1 if the only thing you're going to do with it is check whether it's non-zero?), and is generally easier to explain. So, for various combinations of these reasons, languages like C, Lisp, Javascript, Lua, Perl, Ruby, and VB all do things this way, and so does Python.
Always returning a boolean value from an operator helps to catch some errors (especially in languages where the logical operators and the bitwise operators are easy to confuse), and it allows you to design a language where boolean checks are strictly-typed checks for true instead of just checks for nonzero, it makes the type of the operator easier to write out, and it avoids having to deal with conversion for cases where the two operands are different types (see the ?: operator in C-family languages). So, for various combinations of these reasons, languages like C++, Fortran, Smalltalk, and Haskell all do things this way.
In your question (if I understand it correctly), you're using this feature to be able to write something like:
if (x or 0) < 1:
When x could easily be None. This particular use case isn't very useful, both because the more-explicit x if x else 0 (in Python 2.5 and later) is just as easy to write and probably easier to understand (at least Guido thinks so), but also because None < 1 is the same as 0 < 1 anyway (at least in Python 2.x, so you've always got at least one of the two options)… But there are similar examples where it is useful. Compare these two:
return launchMissiles() or -1
return launchMissiles() if launchMissiles() else -1
The second one will waste a lot of missiles blowing up your enemies in Antarctica twice instead of once.
If you're curious why Python does it this way:
Back in the 1.x days, there was no bool type. You've got falsy values like None, 0, [], (), "", etc., and everything else is true, so who needs explicit False and True? Returning 1 from or would have been silly, because 1 is no more true than [1, 2, 3] or "dsfsdf". By the time bool was added (gradually over two 2.x versions, IIRC), the current logic was already solidly embedded in the language, and changing would have broken a lot of code.
So, why didn't they change it in 3.0? Many Python users, including BDFL Guido, would suggest that you shouldn't use or in this case (at the very least because it's a violation of "TOOWTDI"); you should instead store the result of the expression in a variable, e.g.:
missiles = launchMissiles()
return missiles if missiles else -1
And in fact, Guido has stated that he'd like to ban launchMissiles() or -1, and that's part of the reason he eventually accepted the ternary if-else expression that he'd rejected many times before. But many others disagree, and Guido is a benevolent DFL. Also, making or work the way you'd expect everywhere else, while refusing to do what you want (but Guido doesn't want you to want) here, would actually be pretty complicated.
So, Python will probably always be on the same side as C, Perl, and Lisp here, instead of the same side as Java, Smalltalk, and Haskell.
No language that i know lets you do this. So, why Python do?
Then you don't know many languages. I can't think of one language that I do know that does not exhibit this "shortcircuiting" behaviour.
It does it because it is useful to say:
a = b or K
such that a either becomes b, if b is not None (or otherwise falsy), and if not it gets the default value K.
Actually a number of languages do. See Wikipedia about Short-Circuit Evaluation
For the reason why short-circuit evaluation exists, wikipedia writes:
If both expressions used as conditions are simple boolean variables,
it can be actually faster to evaluate both conditions used in boolean
operation at once, as it always requires a single calculation cycle,
as opposed to one or two cycles used in short-circuit evaluation
(depending on the value of the first).
This behavior is not surprising, and it's quite straightforward if you consider Python has the following features regarding or, and and not logical operators:
Short-circuit evaluation: it only evaluates operands up to where it needs to.
Non-coercing result: the result is one of the operands, not coerced to bool.
And, additionally:
The Truth Value of an object is False only for None, False, 0, "", [], {}. Everything else has a truth value of True (this is a simplification; the correct definition is in the official docs)
Combine those features, and it leads to:
or : if the first operand evaluates as True, short-circuit there and return it. Or return the 2nd operand.
and: if the first operand evaluates as False, short-circuit there and return it. Or return the 2nd operand.
It's easier to understand if you generalize to a chain of operations:
>>> a or b or c or d
>>> a and b and c and d
Here is the "rule of thumb" I've memorized to help me easily predict the result:
or : returns the first "truthy" operand it finds, or the last one.
and: returns the first "falsy" operand it finds, or the last one.
As for your question, on why python behaves like that, well... I think because it has some very neat uses, and it's quite intuitive to understand. A common use is a series of fallback choices, the first "found" (ie, non-falsy) is used. Think about this silly example:
drink = getColdBeer() or pickNiceWine() or random.anySoda or "meh, water :/"
Or this real-world scenario:
username = cmdlineargs.username or configFile['username'] or DEFAULT_USERNAME
Which is much more concise and elegant than the alternative.
As many other answers have pointed out, Python is not alone and many other languages have the same behavior, for both short-circuit (I believe most current languanges are) and non-coercion.
"No language that i know lets you do this. So, why Python do?" You seem to assume that all languages should be the same. Wouldn't you expect innovation in programming languages to produce unique features that people value?
You've just pointed out why it's useful, so why wouldn't Python do it? Perhaps you should ask why other languages don't.
You can take advantage of the special features of the Python or operator out of Boolean contexts. The rule of thumb is still that the result of your Boolean expressions is the first true operand or the last in the line.
Notice that the logical operators (or included) are evaluated before the assignment operator =, so you can assign the result of a Boolean expression to a variable in the same way you do with a common expression:
>>> a = 1
>>> b = 2
>>> var1 = a or b
>>> var1
1
>>> a = None
>>> b = 2
>>> var2 = a or b
>>> var2
2
>>> a = []
>>> b = {}
>>> var3 = a or b
>>> var3
{}
Here, the or operator works as expected, returning the first true operand or the last operand if both are evaluated to false.