I just found this :
a = (None,)
print (a is True)
print (a is False)
print (a == True)
print (a == False)
print (a == None)
print (a is None)
if a : print "hello"
if not a : print "goodbye"
which produces :
False
False
False
False
False
False
hello
So a neither is, nor equals True nor False, but acts as True in an if statement.
Why?
Update :
actually, I've just realized that this isn't as obscure as I thought. I get the same result for a=2, as well (though not for a=0 or a=1, which are considered equal to False and True respectively)
I find almost all the explanations here unhelpful, so here is another try:
The confusion here is based on that testing with "is", "==" and "if" are three different things.
"is" tests identity, that is, if it's the same object. That is obviously not true in this case.
"==" tests value equality, and obviously the only built in objects with the values of True and False are the object True and False (with the exception of the numbers 0 and 1, of any numeric type).
And here comes the important part:
'if' tests on boolean values. That means that whatever expression you give it, it will be converted to either True or False. You can make the same with bool(). And bool((None,)) will return True. The things that will evaluate to False is listed in the docs (linked to by others here)
Now maybe this is only more clear in my head, but at least I tried. :)
a is a one-member tuple, which evaluates to True. is test identity of the object, therefore, you get False in all those test. == test equality of the objects, therefore, you get False again.
in if statement a __bool__ (or __nonzero__) used to evaluate the object, for a non-empty tuple it should return True, therefore you get True. hope that answers your question.
edit: the reason True and False are equal to 1 and 0 respectively is because bool type implemented as a subclass of int type.
Things in python don't have to be one of True or False.
When they're used as a text expression for if/while loops, they're converted to booleans. You can't use is or == to test what they evaluate to. You use bool( thing )
>>> a = (None,)
>>> bool(a)
True
Also note:
>>> 10 == True
False
>>> 10 is True
False
>>> bool(10)
True
TL;DR:
if and == are completely different operations. The if checks the truth value of a variable while == compares two variables. is also compares two variables but it compares if both reference the same object.
So it makes no sense to compare a variable with True, False or None to check it's truth value.
What happens when if is used on a variable?
In Python a check like if implicitly gets the bool of the argument. So
if something:
will be (under the hood) executed like:
if bool(something):
Note that you should never use the latter in your code because it's considered less pythonic and it's slower (because Python then uses two bools: bool(bool(something))). Always use the if something.
If you're interested in how it's evaluated by CPython 3.6:
Note that CPython doesn't exactly use hasattr here. It does check if the type of x implements the method but without going through the __getattribute__ method (hasattr would use that).
In Python2 the method was called __nonzero__ and not __bool__
What happens when variables are compared using ==?
The == will check for equality (often also called "value equality"). However this equality check doesn't coerce the operands (unlike in other programming languages). The value equality in Python is explicitly implemented. So you can do:
>>> 1 == True # because bool subclasses int, True is equal to 1 (and False to 0)
True
>>> 1.0 == True # because float implements __eq__ with int
True
>>> 1+1j == True # because complex implements __eq__ with int
True
However == will default to reference comparison (is) if the comparison isn't implemented by either operand. That's why:
>>> (None, ) == True
False
Because tuple doesn't "support" equality with int and vise-versa. Note that even comparing lists to tuples is "unsupported":
>>> [None] == (None, )
False
Just in case you're interested this is how CPython (3.6) implements equality (the orange arrows indicate if an operation returned the NotImplemented constant):
That's only roughly correct because CPython also checks if the type() of value1 or value2 implements __eq__ (without going through the __getattribute__ method!) before it's called (if it exists) or skipped (if it doesn't exist).
Note that the behavior in Python2 was significantly more lengthy (at least if the methods returned NotImplemented) and Python 2 also supported __cmp__,
What happens when variables are compared using is?
is is generally referred to as reference equality comparison operator. It only returns True if both variables refer to exactly the same object. In general variables that hold the same value can nevertheless refer to different objects:
>>> 1 is 1. # same value, different types
False
>>> a = 500
>>> a is 500 # same value, same type, different instances
False
Note that CPython uses cached values, so sometimes variables that "should" be different instances are actually the same instance. That's why I didn't use 500 is 500 (literals with the same value in the same line are always equal) and why I couldn't use 1 as example (because CPython re-uses the values -5 to 256).
But back to your comparisons: is compares references, that means it's not enough if both operands have the same type and value but they have to be the same reference. Given that they didn't even have the same type (you're comparing tuple with bool and NoneType objects) it's impossible that is would return True.
Note that True, False and None (and also NotImplemented and Ellipsis) are constants and singletons in CPython. That's not just an optimization in these cases.
(None,) is a tuple that contains an element, it's not empty and therefore does not evaluate to False in that context.
Because a=(None,) is a tuple containing a single element None
Try again with a=None and you will see there is a different result.
Also try a=() which is the empty tuple. This has a truth value of false
In Python every type can be converted to bool by using the bool() function or the __nonzero__ method.
Examples:
Sequences (lists, strings, ...) are converted to False when they are empty.
Integers are converted to False when they are equal to 0.
You can define this behavior in your own classes by overriding __nonzero__().
[Edit]
In your code, the tuple (None,) is converted using bool() in the if statements. Since it's non-empty, it evaluates to True.
Related
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
My Google-fu has failed me.
In Python, are the following two tests for equality equivalent?
n = 5
# Test one.
if n == 5:
print 'Yay!'
# Test two.
if n is 5:
print 'Yay!'
Does this hold true for objects where you would be comparing instances (a list say)?
Okay, so this kind of answers my question:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
So == tests value where is tests to see if they are the same object?
is will return True if two variables point to the same object (in memory), == if the objects referred to by the variables are equal.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
The same holds true for string literals:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
Please see this question as well.
There is a simple rule of thumb to tell you when to use == or is.
== is for value equality. Use it when you would like to know if two objects have the same value.
is is for reference equality. Use it when you would like to know if two references refer to the same object.
In general, when you are comparing something to a simple type, you are usually checking for value equality, so you should use ==. For example, the intention of your example is probably to check whether x has a value equal to 2 (==), not whether x is literally referring to the same object as 2.
Something else to note: because of the way the CPython reference implementation works, you'll get unexpected and inconsistent results if you mistakenly use is to compare for reference equality on integers:
>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
That's pretty much what we expected: a and b have the same value, but are distinct entities. But what about this?
>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
This is inconsistent with the earlier result. What's going on here? It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons. Here's an example demonstrating this:
>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
...
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False
This is another obvious reason not to use is: the behavior is left up to implementations when you're erroneously using it for value equality.
Is there a difference between == and is in Python?
Yes, they have a very important difference.
==: check for equality - the semantics are that equivalent objects (that aren't necessarily the same object) will test as equal. As the documentation says:
The operators <, >, ==, >=, <=, and != compare the values of two objects.
is: check for identity - the semantics are that the object (as held in memory) is the object. Again, the documentation says:
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object. Object identity is
determined using the id() function. x is not y yields the inverse
truth value.
Thus, the check for identity is the same as checking for the equality of the IDs of the objects. That is,
a is b
is the same as:
id(a) == id(b)
where id is the builtin function that returns an integer that "is guaranteed to be unique among simultaneously existing objects" (see help(id)) and where a and b are any arbitrary objects.
Other Usage Directions
You should use these comparisons for their semantics. Use is to check identity and == to check equality.
So in general, we use is to check for identity. This is usually useful when we are checking for an object that should only exist once in memory, referred to as a "singleton" in the documentation.
Use cases for is include:
None
enum values (when using Enums from the enum module)
usually modules
usually class objects resulting from class definitions
usually function objects resulting from function definitions
anything else that should only exist once in memory (all singletons, generally)
a specific object that you want by identity
Usual use cases for == include:
numbers, including integers
strings
lists
sets
dictionaries
custom mutable objects
other builtin immutable objects, in most cases
The general use case, again, for ==, is the object you want may not be the same object, instead it may be an equivalent one
PEP 8 directions
PEP 8, the official Python style guide for the standard library also mentions two use-cases for is:
Comparisons to singletons like None should always be done with is or
is not, never the equality operators.
Also, 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. The other value might have a type (such
as a container) that could be false in a boolean context!
Inferring equality from identity
If is is true, equality can usually be inferred - logically, if an object is itself, then it should test as equivalent to itself.
In most cases this logic is true, but it relies on the implementation of the __eq__ special method. As the docs say,
The default behavior for equality comparison (== and !=) is based on
the identity of the objects. Hence, equality comparison of instances
with the same identity results in equality, and equality comparison of
instances with different identities results in inequality. A
motivation for this default behavior is the desire that all objects
should be reflexive (i.e. x is y implies x == y).
and in the interests of consistency, recommends:
Equality comparison should be reflexive. In other words, identical
objects should compare equal:
x is y implies x == y
We can see that this is the default behavior for custom objects:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
The contrapositive is also usually true - if somethings test as not equal, you can usually infer that they are not the same object.
Since tests for equality can be customized, this inference does not always hold true for all types.
An exception
A notable exception is nan - it always tests as not equal to itself:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
Checking for identity can be much a much quicker check than checking for equality (which might require recursively checking members).
But it cannot be substituted for equality where you may find more than one object as equivalent.
Note that comparing equality of lists and tuples will assume that identity of objects are equal (because this is a fast check). This can create contradictions if the logic is inconsistent - as it is for nan:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
A Cautionary Tale:
The question is attempting to use is to compare integers. You shouldn't assume that an instance of an integer is the same instance as one obtained by another reference. This story explains why.
A commenter had code that relied on the fact that small integers (-5 to 256 inclusive) are singletons in Python, instead of checking for equality.
Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. β gwg
It worked in development. It may have passed some unittests.
And it worked in production - until the code checked for an integer larger than 256, at which point it failed in production.
This is a production failure that could have been caught in code review or possibly with a style-checker.
Let me emphasize: do not use is to compare integers.
== determines if the values are equal, while is determines if they are the exact same object.
What's the difference between is and ==?
== and is are different comparison! As others already said:
== compares the values of the objects.
is compares the references of the objects.
In Python names refer to objects, for example in this case value1 and value2 refer to an int instance storing the value 1000:
value1 = 1000
value2 = value1
Because value2 refers to the same object is and == will give True:
>>> value1 == value2
True
>>> value1 is value2
True
In the following example the names value1 and value2 refer to different int instances, even if both store the same integer:
>>> value1 = 1000
>>> value2 = 1000
Because the same value (integer) is stored == will be True, that's why it's often called "value comparison". However is will return False because these are different objects:
>>> value1 == value2
True
>>> value1 is value2
False
When to use which?
Generally is is a much faster comparison. That's why CPython caches (or maybe reuses would be the better term) certain objects like small integers, some strings, etc. But this should be treated as implementation detail that could (even if unlikely) change at any point without warning.
You should only use is if you:
want to check if two objects are really the same object (not just the same "value"). One example can be if you use a singleton object as constant.
want to compare a value to a Python constant. The constants in Python are:
None
True1
False1
NotImplemented
Ellipsis
__debug__
classes (for example int is int or int is float)
there could be additional constants in built-in modules or 3rd party modules. For example np.ma.masked from the NumPy module)
In every other case you should use == to check for equality.
Can I customize the behavior?
There is some aspect to == that hasn't been mentioned already in the other answers: It's part of Pythons "Data model". That means its behavior can be customized using the __eq__ method. For example:
class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
This is just an artificial example to illustrate that the method is really called:
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
Note that by default (if no other implementation of __eq__ can be found in the class or the superclasses) __eq__ uses is:
class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
So it's actually important to implement __eq__ if you want "more" than just reference-comparison for custom classes!
On the other hand you cannot customize is checks. It will always compare just if you have the same reference.
Will these comparisons always return a boolean?
Because __eq__ can be re-implemented or overridden, it's not limited to return True or False. It could return anything (but in most cases it should return a boolean!).
For example with NumPy arrays the == will return an array:
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False, True, False, False, False, False, False, False, False], dtype=bool)
But is checks will always return True or False!
1 As Aaron Hall mentioned in the comments:
Generally you shouldn't do any is True or is False checks because one normally uses these "checks" in a context that implicitly converts the condition to a boolean (for example in an if statement). So doing the is True comparison and the implicit boolean cast is doing more work than just doing the boolean cast - and you limit yourself to booleans (which isn't considered pythonic).
Like PEP8 mentions:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
They are completely different. is checks for object identity, while == checks for equality (a notion that depends on the two operands' types).
It is only a lucky coincidence that "is" seems to work correctly with small integers (e.g. 5 == 4+1). That is because CPython optimizes the storage of integers in the range (-5 to 256) by making them singletons. This behavior is totally implementation-dependent and not guaranteed to be preserved under all manner of minor transformative operations.
For example, Python 3.5 also makes short strings singletons, but slicing them disrupts this behavior:
>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
https://docs.python.org/library/stdtypes.html#comparisons
is tests for identity
== tests for equality
Each (small) integer value is mapped to a single value, so every 3 is identical and equal. This is an implementation detail, not part of the language spec though
Your answer is correct. The is operator compares the identity of two objects. The == operator compares the values of two objects.
An object's identity never changes once it has been created; you may think of it as the object's address in memory.
You can control comparison behaviour of object values by defining a __cmp__ method or a rich comparison method like __eq__.
Have a look at Stack Overflow question Python's βisβ operator behaves unexpectedly with integers.
What it mostly boils down to is that "is" checks to see if they are the same object, not just equal to each other (the numbers below 256 are a special case).
In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
As the other people in this post answer the question in details the difference between == and is for comparing Objects or variables, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.
For string comparison, make sure to use == instead of is:
str = 'hello'
if (str is 'hello'):
print ('str is hello')
if (str == 'hello'):
print ('str == hello')
Out:
str is hello
str == hello
But in the below example == and is will get different results:
str2 = 'hello sam'
if (str2 is 'hello sam'):
print ('str2 is hello sam')
if (str2 == 'hello sam'):
print ('str2 == hello sam')
Out:
str2 == hello sam
Conclusion and Analysis:
Use is carefully to compare between strings.
Since is for comparing objects and since in Python 3+ every variable such as string interpret as an object, let's see what happened in above paragraphs.
In python there is id function that shows a unique constant of an object during its lifetime. This id is using in back-end of Python interpreter to compare two objects using is keyword.
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
But
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
As John Feminella said, most of the time you will use == and != because your objective is to compare values. I'd just like to categorise what you would do the rest of the time:
There is one and only one instance of NoneType i.e. None is a singleton. Consequently foo == None and foo is None mean the same. However the is test is faster and the Pythonic convention is to use foo is None.
If you are doing some introspection or mucking about with garbage collection or checking whether your custom-built string interning gadget is working or suchlike, then you probably have a use-case for foo is bar.
True and False are also (now) singletons, but there is no use-case for foo == True and no use case for foo is True.
Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement
== if the objects referred to by the variables are equal
from above answers should be read as
== if the objects referred to by the variables are equal and objects belonging to the same type/class
. I arrived at this conclusion based on the below test:
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)
print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))
print(list1 == tuple1)
print(list1 is tuple1)
Here the contents of the list and tuple are same but the type/class are different.
I am learning python, but I'm a bit confused by the following result.
In [41]: 1 == True
Out[41]: True
In [42]: if(1):
...: print('111')
...:
111
In [43]: ... == True
Out[43]: False <===== why this is False while '1 == True' is True in previous sample
In [44]: if (...): <==== here ... just behaves like True
...: print('...')
...:
...
According to the documentation, ... has a truth value of True.
But I still feel the above code a bit inconsistent.
...And something more interesting:
In [48]: 2==True
Out[48]: False <===== why 1==True returns True while 2==True returns False?
In [49]: if(2):
...: print('222')
...:
222
You're mixing two concepts: equality testing and truth-value testing. They are not the same in Python.
I think what triggered the question is that Python does an implicit casting when you do if something (it casts the something to bool) but it does not do implicit casting when you do something1 == something2.
Pythons data model actually explains how these operations are done:
Truth-value testing
It starts by checking if the object implements the __bool__ method and if it does it uses the returned boolean.
If it doesn't define a __bool__ method it looks at the __len__ method. If it's implemented it will use the result of len(obj) != 0.
If it doesn't have either the object is considered True.
For integers the __bool__ method returns True except when the integer value is 0 (then it's False).
The Ellipsis object (... is the Ellipsis object) on the other hand doesn't implement __bool__ or __len__ so it's always True.
Equality testing
Equality testing relies on the __eq__ method of both arguments. It's more a chain of operations:
It checks if the first operand implements __eq__ when the second operand is passed as argument.
If it doesn't then it checks if the second operand implements __eq__ when the first operand is passed as argument.
If it doesn't then Python checks for object identity (if they are the same object - similar to pointer comparisons in C-like languages)
The order of these operations may vary.1
For built-in Python types these operations are explicitly implemented. For example integers implement __eq__ but the CHECK_BINOP makes sure that it returns NotImplemented if the other one isn't an integer.
The Ellipsis object doesn't implement __eq__ at all.
So when you compare integers and Ellipsis Python will always fallback to object identity and so it will always return False.
On the other hand booleans are a subclass of integers so they actually compare with int (they are another int after all). The booleans are implemented as 1 (True) and 0 (False). So they compare equal:
>>> 1 == True
True
>>> 0 == False
True
>>> 1 == False
False
>>> 0 == True
False
Even though the source code is probably hard to understand I hope I explained the concepts well enough (the source code is for the CPython implementation, the implementation in other Python implementations like PyPy, IronPython may differ!). The important take-away message should be that Python doesn't do implicit conversions in equality checks and equality testing is not related to truth value testing at all. The built-in types are implemented that they almost always give senseable results:
all number-types implement equality in some way (floats compare to integers, complex compare to integers and floats)
and everything not-zero and not-empty is truthy.
However if you create your own classes you can override equality and truth value testing as you like (and then you can spread a lot of confusion)!
1 In some cases the order is changed:
If the second operand is a subclass of the first operand the first two steps are reversed.
For some implicit equality checks the object identity is checked before any __eq__ methods are called. For example when checking if some item is in a list, i.e. 1 in [1,2,3].
Any object can be tested for "truthiness":
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
None
False
zero of any numeric type, for example, 0, 0.0, 0j.
any empty sequence, for example, '', (), [].
any empty mapping, for example, {}.
instances of user-defined classes, if the class defines a bool() or len() method, when that method returns the integer zero or bool value False. [1]
All other values are considered true β so objects of many types are always true.
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)
So it's not hard to see that if ... will enter the branch. The Ellipsis object is considered true. However that doesn't mean it has to be equal to True. Just the bool(...) == True!
The if will implicitly call bool on the condition, so:
if ...:
# something
will be evaluated as if you had written:
if bool(...):
# something
and:
>>> bool(...)
True
>>> bool(1)
True
>>> bool(2)
True
However there's one catch here. True is equal to 1 and False equal to 0, but that's just because bool subclasses integer in python.
In python most (all?) objects have a bool value. The meaning behind "has a truth value of True" means that bool(obj) evaluates to True.
On the other hand, True is treated as 1 in many cases (and False as 0) which you can see when you do stuff like:
sum([True, True, False])
# (1 + 1 + 0) -> 2
That is why you get 1 == True --> True
There is a more explicit explanation in the documentation:
Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true). In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively
From the type-hierarchy itself in the docs:
These represent the truth values False and True. The two objects representing the values False and True are the only Boolean objects. The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings "False" or "True" are returned, respectively.
I believe it's 1 == True here is that's weird, not that ... != True.
1 equals with True because in Python booleans are subclass of integers (because of PEP-285). See yourself:
>>> issubclass(bool, int)
True
In PHP you use the === notation to test for TRUE or FALSE distinct from 1 or 0.
For example if FALSE == 0 returns TRUE, if FALSE === 0 returns FALSE. So when doing string searches in base 0 if the position of the substring in question is right at the beginning you get 0 which PHP can distinguish from FALSE.
Is there a means of doing this in Python?
In Python,
The is operator tests for identity (False is False, 0 is not False).
The == operator which tests for logical equality (and thus 0 == False).
Technically neither of these is exactly equivalent to PHP's ===, which compares logical equality and type - in Python, that'd be a == b and type(a) is type(b).
Some other differences between is and ==:
Mutable type literals
{} == {}, but {} is not {} (and the same holds true for lists and other mutable types)
However, if a = {}, then a is a (because in this case it's a reference to the same instance)
Strings
"a"*255 is not "a"*255", but "a"*20 is "a"*20 in most implementations, due to how Python handles string interning. This behavior isn't guaranteed, though, and you probably shouldn't be using is in this case. "a"*255 == "a"*255 and is almost always the right comparison to use.
Numbers
12345 is 12345 but 12345 is not 12345 + 1 - 1 in most implementations, similarly. You pretty much always want to use equality for these cases.
if something is False:
is what you should do
if something is None:
also works
the moral is use is ... (although you should never do something is 123457, or simillar)
for why you should never do this with ints and things see http://ideone.com/iKmWCn
The strict equivalent of x === y in Python is type(x) is type(y) and x == y. You don't really want to do this as Python is duck typed. If an object has the appropriate method or attribute then you shouldn't be too worried about its actual type.
If you are checking for a specific unique object such as (True, False, None, or a class) then you should use is and is not. For example: x is True.
I think that I fully understand this, but I just want to make sure since I keep seeing people say to never ever test against True, False, or None.
They suggest that routines should raise an error rather than return False or None. Anyway, I have many situations where I simply want to know if a flag is set or not so my function returns True or False. There are other situations where I have a function return None if there was no useful result. From my thinking, neither is problematic so long as I realize that I should never use:
if foo == True
if foo == False
if foo == None
and should instead use:
if foo is True
if foo is False
if foo is None
since True, False, and None are all singletons and will always evaluate the way I expect when using "is" rather than "==". Am I wrong here?
Along the same lines, would it be more Pythonic to modify the functions that sometimes return None so that they raise an error instead?
Say I have an instance method called "get_attr()" that retrieves an attribute from some file. In the case where it finds that the attribute I requested does not exist, is it appropriate to return None? Would it be better to have them raise an error and catch it later?
The advice isn't that you should never use True, False, or None. It's just that you shouldn't use if x == True.
if x == True is silly because == is just a binary operator! It has a return value of either True or False, depending on whether its arguments are equal or not. And if condition will proceed if condition is true. So when you write if x == True Python is going to first evaluate x == True, which will become True if x was True and False otherwise, and then proceed if the result of that is true. But if you're expecting x to be either True or False, why not just use if x directly!
Likewise, x == False can usually be replaced by not x.
There are some circumstances where you might want to use x == True. This is because an if statement condition is "evaluated in Boolean context" to see if it is "truthy" rather than testing exactly against True. For example, non-empty strings, lists, and dictionaries are all considered truthy by an if statement, as well as non-zero numeric values, but none of those are equal to True. So if you want to test whether an arbitrary value is exactly the value True, not just whether it is truthy, when you would use if x == True. But I almost never see a use for that. It's so rare that if you do ever need to write that, it's worth adding a comment so future developers (including possibly yourself) don't just assume the == True is superfluous and remove it.
Using x is True instead is actually worse. You should never use is with basic built-in immutable types like Booleans (True, False), numbers, and strings. The reason is that for these types we care about values, not identity. == tests that values are the same for these types, while is always tests identities.
Testing identities rather than values is bad because an implementation could theoretically construct new Boolean values rather than go find existing ones, leading to you having two True values that have the same value, but they are stored in different places in memory and have different identities. In practice I'm pretty sure True and False are always reused by the Python interpreter so this won't happen, but that's really an implementation detail. This issue trips people up all the time with strings, because short strings and literal strings that appear directly in the program source are recycled by Python so 'foo' is 'foo' always returns True. But it's easy to construct the same string 2 different ways and have Python give them different identities. Observe the following:
>>> stars1 = ''.join('*' for _ in xrange(100))
>>> stars2 = '*' * 100
>>> stars1 is stars2
False
>>> stars1 == stars2
True
EDIT: So it turns out that Python's equality on Booleans is a little unexpected (at least to me):
>>> True is 1
False
>>> True == 1
True
>>> True == 2
False
>>> False is 0
False
>>> False == 0
True
>>> False == 0.0
True
The rationale for this, as explained in the notes when bools were introduced in Python 2.3.5, is that the old behaviour of using integers 1 and 0 to represent True and False was good, but we just wanted more descriptive names for numbers we intended to represent truth values.
One way to achieve that would have been to simply have True = 1 and False = 0 in the builtins; then 1 and True really would be indistinguishable (including by is). But that would also mean a function returning True would show 1 in the interactive interpreter, so what's been done instead is to create bool as a subtype of int. The only thing that's different about bool is str and repr; bool instances still have the same data as int instances, and still compare equality the same way, so True == 1.
So it's wrong to use x is True when x might have been set by some code that expects that "True is just another way to spell 1", because there are lots of ways to construct values that are equal to True but do not have the same identity as it:
>>> a = 1L
>>> b = 1L
>>> c = 1
>>> d = 1.0
>>> a == True, b == True, c == True, d == True
(True, True, True, True)
>>> a is b, a is c, a is d, c is d
(False, False, False, False)
And it's wrong to use x == True when x could be an arbitrary Python value and you only want to know whether it is the Boolean value True. The only certainty we have is that just using x is best when you just want to test "truthiness". Thankfully that is usually all that is required, at least in the code I write!
A more sure way would be x == True and type(x) is bool. But that's getting pretty verbose for a pretty obscure case. It also doesn't look very Pythonic by doing explicit type checking... but that really is what you're doing when you're trying to test precisely True rather than truthy; the duck typing way would be to accept truthy values and allow any user-defined class to declare itself to be truthy.
If you're dealing with this extremely precise notion of truth where you not only don't consider non-empty collections to be true but also don't consider 1 to be true, then just using x is True is probably okay, because presumably then you know that x didn't come from code that considers 1 to be true. I don't think there's any pure-python way to come up with another True that lives at a different memory address (although you could probably do it from C), so this shouldn't ever break despite being theoretically the "wrong" thing to do.
And I used to think Booleans were simple!
End Edit
In the case of None, however, the idiom is to use if x is None. In many circumstances you can use if not x, because None is a "falsey" value to an if statement. But it's best to only do this if you're wanting to treat all falsey values (zero-valued numeric types, empty collections, and None) the same way. If you are dealing with a value that is either some possible other value or None to indicate "no value" (such as when a function returns None on failure), then it's much better to use if x is None so that you don't accidentally assume the function failed when it just happened to return an empty list, or the number 0.
My arguments for using == rather than is for immutable value types would suggest that you should use if x == None rather than if x is None. However, in the case of None Python does explicitly guarantee that there is exactly one None in the entire universe, and normal idiomatic Python code uses is.
Regarding whether to return None or raise an exception, it depends on the context.
For something like your get_attr example I would expect it to raise an exception, because I'm going to be calling it like do_something_with(get_attr(file)). The normal expectation of the callers is that they'll get the attribute value, and having them get None and assume that was the attribute value is a much worse danger than forgetting to handle the exception when you can actually continue if the attribute can't be found. Plus, returning None to indicate failure means that None is not a valid value for the attribute. This can be a problem in some cases.
For an imaginary function like see_if_matching_file_exists, that we provide a pattern to and it checks several places to see if there's a match, it could return a match if it finds one or None if it doesn't. But alternatively it could return a list of matches; then no match is just the empty list (which is also "falsey"; this is one of those situations where I'd just use if x to see if I got anything back).
So when choosing between exceptions and None to indicate failure, you have to decide whether None is an expected non-failure value, and then look at the expectations of code calling the function. If the "normal" expectation is that there will be a valid value returned, and only occasionally will a caller be able to work fine whether or not a valid value is returned, then you should use exceptions to indicate failure. If it will be quite common for there to be no valid value, so callers will be expecting to handle both possibilities, then you can use None.
Use if foo or if not foo. There isn't any need for either == or is for that.
For checking against None, is None and is not None are recommended. This allows you to distinguish it from False (or things that evaluate to False, like "" and []).
Whether get_attr should return None would depend on the context. You might have an attribute where the value is None, and you wouldn't be able to do that. I would interpret None as meaning "unset", and a KeyError would mean the key does not exist in the file.
If checking for truth:
if foo
For false:
if not foo
For none:
if foo is None
For non-none:
if foo is not None
For getattr() the correct behaviour is not to return None, but raise an AttributError error instead - unless your class is something like defaultdict.
Concerning whether to raise an exception or return None: it depends on the use case. Either can be Pythonic.
Look at Python's dict class for example. x[y] hooks into dict.__getitem__, and it raises a KeyError if key is not present. But the dict.get method returns the second argument (which is defaulted to None) if key is not present. They are both useful.
The most important thing to consider is to document that behaviour in the docstring, and make sure that your get_attr() method does what it says it does.
To address your other questions, use these conventions:
if foo:
# For testing truthiness
if not foo:
# For testing falsiness
if foo is None:
# Testing .. Noneliness ?
if foo is not None:
# Check explicitly avoids common bugs caused by empty sequences being false
Functions that return True or False should probably have a name that makes this obvious to improve code readability:
def is_running_on_windows():
return os.name == 'nt'
In Python 3 you can "type-hint" that:
>>> def is_running_on_windows() -> bool:
... return os.name == 'nt'
...
>>> is_running_on_windows.__annotations__
{'return': bool}
You can directly check that a variable contains a value or not, like if var or not var.
In the examples in PEP 8 (Style Guide for Python Code) document, I have seen that foo is None or foo is not None are being used instead of foo == None or foo != None.
Also using if boolean_value is recommended in this document instead of if boolean_value == True or if boolean_value is True. So I think if this is the official Python way. We Python guys should go on this way, too.
One thing to ensure is that nothing can reassign your variable. If it is not a Boolean in the end, relying on truthiness will lead to bugs. The beauty of conditional programming in dynamically typed languages :).
The following prints "no".
x = False
if x:
print 'yes'
else:
print 'no'
Now let's change x.
x = 'False'
Now the statement prints "yes", because the string is truthy.
if x:
print 'yes'
else:
print 'no'
This statement, however, correctly outputs "no".
if x == True:
print 'yes'
else:
print 'no'
In the case of your fictional getattr function, if the requested attribute always should be available but isn't then throw an error. If the attribute is optional then return None.
For True, not None:
if foo:
For false, None:
if not foo:
Does Python actually contain a Boolean value? I know that you can do:
checker = 1
if checker:
#dostuff
But I'm quite pedantic and enjoy seeing booleans in Java. For instance:
Boolean checker;
if (someDecision)
{
checker = true;
}
if(checker)
{
//some stuff
}
Is there such a thing as a Boolean in Python? I can't seem to find anything like it in the documentation.
checker = None
if some_decision:
checker = True
if checker:
# some stuff
[Edit]
For more information: http://docs.python.org/library/functions.html#bool
Your code works too, since 1 is converted to True when necessary.
Actually Python didn't have a boolean type for a long time (as in old C), and some programmers still use integers instead of booleans.
The boolean builtins are capitalized: True and False.
Note also that you can do checker = bool(some_decision) as a bit of shorthand -- bool will only ever return True or False.
It's good to know for future reference that classes defining __nonzero__ or __len__ will be True or False depending on the result of those functions, but virtually every other object's boolean result will be True (except for the None object, empty sequences, and numeric zeros).
True ... and False obviously.
Otherwise, None evaluates to False, as does the integer 0 and also the float 0.0 (although I wouldn't use floats like that).
Also, empty lists [], empty tuplets (), and empty strings '' or "" evaluate to False.
Try it yourself with the function bool():
bool([])
bool(['a value'])
bool('')
bool('A string')
bool(True) # ;-)
bool(False)
bool(0)
bool(None)
bool(0.0)
bool(1)
etc..
Boolean types are defined in documentation:
http://docs.python.org/library/stdtypes.html#boolean-values
Quoted from doc:
Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true). In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively. The built-in function bool() can be used to cast any value to a Boolean, if the value can be interpreted as a truth value (see section Truth Value Testing above).
They are written as False and True, respectively.
So in java code remove braces, change true to True and you will be ok :)
Yes, there is a bool data type (which inherits from int and has only two values: True and False).
But also Python has the boolean-able concept for every object, which is used when function bool([x]) is called.
See more: object.nonzero and boolean-value-of-objects-in-python.
Unlike Java where you would declare boolean flag = True, in Python you can just declare myFlag = True
Python would interpret this as a boolean variable
Booleans in python are subclass of integer. Constructor of booleans is bool. bool class inherits from int class.
issubclass(bool,int) // will return True
isinstance(True,bool) , isinstance(False,bool) //they both True
True and False are singleton objects. they will retain same memory address throughout the lifetime of your app. When you type True, python memory manager will check its address and will pull the value '1'. for False its value is '0'.
Comparisons of any boolean expression to True or False can be performed using either is (identity) or == (equality) operator.
int(True) == 1
int(False) == 0
But note that True and '1' are not the same objects. You can check:
id(True) == id(1) // will return False
you can also easily see that
True > False // returns true cause 1>0
any integer operation can work with the booleans.
True + True + True =3
All objects in python have an associated truth value. Every object has True value except:
None
False
0 in any numeric type (0,0.0,0+0j etc)
empty sequences (list, tuple, string)
empty mapping types (dictionary, set, etc)
custom classes that implement __bool__ or __len__ method that returns False or 0.
every class in python has truth values defined by a special instance method:
__bool__(self) OR
__len__
When you call bool(x) python will actually execute
x.__bool__()
if instance x does not have this method, then it will execute
x.__len__()
if this does not exist, by default value is True.
For Example for int class we can define bool as below:
def __bool__(self):
return self != 0
for bool(100), 100 !=0 will return True. So
bool(100) == True
you can easily check that bool(0) will be False. with this for instances of int class only 0 will return False.
another example= bool([1,2,3])
[1,2,3] has no __bool__() method defined but it has __len__() and since its length is greater than 0, it will return True. Now you can see why empty lists return False.