I'm looking for a (semi)-official statement on this, but couldn't find
one with normal googling. Can someone please send a link?
>From http://www.python.org/dev/peps/pep-0008/ ,
2nd bullet under "Programming Recommendations":
- Comparisons to singletons like None should always be done with
'is' or 'is not', never the equality operators.
Just FYI, `is` compares object identity (pointer equality) whereas ==
checks for value equivalence (which causes a method call). This is why
it's significantly faster.
But the main reason is because it's idiomatic.
Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com
>>> import copy
>>> n = copy.copy(None)
>>> id(n)
1555754480
>>> id(None)
1555754480
>>>
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Does the interpreter guarantee the same for False and True bools?
Yes. I know that there are the PyObject* structs defined for you
Py_True, Py_False and Py_None in the C level. Confusingly enough, the
integers -5 through 257 are also singletons where the is test will
work, but any int out of that range will not.
>>> def copy_id(x):
... id1, id2 = id(x), id(copy.deepcopy(x))
... print "Equal: %x %s %x" % (id1, ('==' if id1 == id2 else '!
='), id2)
...
...
>>> copy_id(a())
Equal: a8fc90 != f32370
>>> copy_id(1)
Equal: 9559c8 == 9559c8
>>> copy_id(None)
Equal: 1e1da9f0 == 1e1da9f0
>>> copy_id(True)
Equal: 1e1c5ec4 == 1e1c5ec4
>>> copy_id(False)
Equal: 1e1c5eb8 == 1e1c5eb8
>>> copy_id("Hello")
Equal: 1058840 == 1058840
>>> copy_id([])
Equal: 1067030 != 10673f0
... large equal integers are not identical in memory location ...
In [34]: x = 19591
In [35]: y = 19590+1
In [36]: id(x), id(y)
Out[36]: (17937008, 17936588)
... but small ones are ...
In [40]: x = 2
In [41]: y = 1+1
In [42]: id(x), id(y)
Out[42]: (9787836, 9787836)
Why do you think it matters? Consider the circumstances under which
you would use each of the following:
if some_name == True:
if some_name is True:
if some_name:
Small ints are cached. You should use "is True" or "is False" in Python
2.x because user can overwrite the True and False objects. In Python 3.0
both True and False are truly immutable and global singletons -- and
keywords, too. The mutable nature of the name "True" makes a "while
True:" loop sightly slower than a "while 1:" loop, too.
Python 2.5:
>>> None = 1
File "<stdin>", line 1
SyntaxError: assignment to None
>>> True = 1
>>>
Python 3.0
>>> True = 1
File "<stdin>", line 1
SyntaxError: assignment to keyword
>>> None = 1
File "<stdin>", line 1
SyntaxError: assignment to keyword
The three lines translate (roughly) into:
if some_name.__eq__(True):
if id(some_name) == id(True):
if some_name.__nonzero__(): # may check for __len__() != 0, too.
In almost every case (99.99%) you want the last variant. The second variant
Intellectual curiosity hence why I asked the question. It doesn't
matter if I know why the sky is blue but it's interesting to know
regardless.
> Hi -- Some time ago I ran across a comment recommending using <var> is
> None instead of <var> == None (also <var> is not None, etc.)
That entirely depends on whether you wish to test for something which
*is* None or something with *equals* None. Those two things have
different meanings.
I wonder, do newbies actually get the impression from somewhere that "is"
is a synonym for "=="?
> My own
> testing indicates that the former beats the latter by about 30% on
> average. Not a log for a single instruction but it can add up in large
> projects.
If you have a "large" project where the time taken to do comparisons to
None is a significant portion of the total time, I'd be very surprised.
var is None is a micro-optimization, but that's not why we do it. We do
it because usually the correct test is whether var *is* None and not
merely equal to None. Any random object might happen to equal None
(admittedly most objects don't), but only None is None.
--
Steven
Actually, for None, those two things *are* the same. If something
*equals* None, it also *is* None. This is a consequence of the fact
that there is only ever one value of None anywhere in the system.
> I wonder, do newbies actually get the impression from somewhere that "is"
> is a synonym for "=="?
>
Yes. Such questions pop up regularly, and are usually dealt with quickly.
>
>
>
>> My own
>> testing indicates that the former beats the latter by about 30% on
>> average. Not a log for a single instruction but it can add up in large
>> projects.
>>
>
> If you have a "large" project where the time taken to do comparisons to
> None is a significant portion of the total time, I'd be very surprised.
>
> var is None is a micro-optimization, but that's not why we do it. We do
> it because usually the correct test is whether var *is* None and not
> merely equal to None. Any random object might happen to equal None
> (admittedly most objects don't), but only None is None.
>
>
You don't have that quite right. The only way something can *equal*
None is if it *is* None.
None is not a value an object can have, but rather it is a (singleton)
object that can be referenced. Setting something *equal* to None is
accomplished by making it refer to the single None object, at which
point it *is* None.
Gary Herron
>
>
> var is None is a micro-optimization, but that's not why we do it. We do
> it because usually the correct test is whether var *is* None and not
> merely equal to None. Any random object might happen to equal None
> (admittedly most objects don't), but only None is None.
Additionally, some objects that use rich comparisons to return other objects and not
booleans will simply fail when compared with None. The situations where you are testing
for None are frequently situations where you don't really know the kind of object you
might be getting, either.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
> If something
> *equals* None, it also *is* None. This is a consequence of the fact
> that there is only ever one value of None anywhere in the system.
...
> The only way something can *equal* None is if it *is* None.
>>> class Empty:
... def __eq__(self, other):
... return not bool(other)
...
>>> e = Empty()
>>> e == None
True
>>> e is None
False
--
Steven
> I wonder, do newbies actually get the impression from somewhere that "is"
> is a synonym for "=="?
>
Who knows. But if they do they can easily be reeducated.
>
>
>> My own
>> testing indicates that the former beats the latter by about 30% on
>> average. Not a log for a single instruction but it can add up in large
>> projects.
>
> If you have a "large" project where the time taken to do comparisons to
> None is a significant portion of the total time, I'd be very surprised.
>
> var is None is a micro-optimization, but that's not why we do it. We do
> it because usually the correct test is whether var *is* None and not
> merely equal to None. Any random object might happen to equal None
> (admittedly most objects don't), but only None is None.
>
Of course there can be pathological objects with bizarre comparison
methods. And the "is" test helps avoid them.
> Steven D'Aprano wrote:
>> On Fri, 23 Jan 2009 14:58:34 -0500, Gerald Britton wrote:
>>
>>> Hi -- Some time ago I ran across a comment recommending using <var> is
>>> None instead of <var> == None (also <var> is not None, etc.)
>>
>> That entirely depends on whether you wish to test for something which
>> *is* None or something with *equals* None. Those two things have
>> different meanings.
>>
> No they don't, because the language *guarantees* the None object is a
> singleton, so anything that *equals* None *is* None.
Twice in one day. Have they put funny chemicals in the water over there?
*wink*
Steve, in case you missed my earlier response:
>>> class Empty:
... def __eq__(self, other):
... return not bool(other)
...
>>> e = Empty()
>>> e == None
True
>>> e is None
False
An instance that compares equal to anything false doesn't strike me as
particularly bizarre or pathological. For instance, the Python Cookbook
has an implementation for the Null object pattern. The implementation
given compares unequal to everything, but suggests defining an
appropriate __eq__ if you need different behaviour.
--
Steven
> Steve, in case you missed my earlier response:
>
>>>> class Empty:
> ... def __eq__(self, other):
> ... return not bool(other)
> ...
>>>> e = Empty()
>>>> e == None
> True
>>>> e is None
> False
>
>
> An instance that compares equal to anything false doesn't strike me as
> particularly bizarre or pathological. For instance, the Python Cookbook
> has an implementation for the Null object pattern. The implementation
> given compares unequal to everything, but suggests defining an
> appropriate __eq__ if you need different behaviour.
>
Sure, my syllogism was not strictly true, hence my final quote:
> Of course there can be pathological objects with bizarre comparison
> methods. And the "is" test helps avoid them.
Personally I believe that the Empty class is at least slightly pathological.
Yes. Bool(x) should return one of the two existing instances.
In 2.x, the *names* 'True' and 'False' can be rebound because bool is
new and people write
try:
False,True
except NameError:
False,True = 0,1
to make code back compatible.
In 3.0, the names are keywords, just like 'None' and cannot be rebound,
so x is True is guaranteed to answer whether x *is* the true object.
Back before rebinding 'None' was prohibited, 'is None' was not
completely guaranteed either (absent reading the rest of a file to be
sure no rebinding would be done).
> In 3.0, the names are keywords, just like 'None' and cannot be rebound,
> so x is True is guaranteed to answer whether x *is* the true object.
>
> Back before rebinding 'None' was prohibited, 'is None' was not
> completely guaranteed either (absent reading the rest of a file to be
> sure no rebinding would be done).
>
And that was a bug too, in this case one that *was* removed in 2.4, I
believe. Don't have 2.3 lying around just now.
Python 2.4.3 (#1, May 24 2008, 13:47:28)
[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> None = 3
SyntaxError: assignment to None
>> In 2.x, the *names* 'True' and 'False' can be rebound because bool is
>> new and people write
>> try:
>> False,True
>> except NameError:
>> False,True = 0,1
>>
>> to make code back compatible.
>>
> I would claim that the ability to rebind True and False is a simple bug,
> though one not likely to be fixed in an 2.x release. The code above
> doesn't rebind True and False in interpreters that have them ...
In pre-bool 2.x, people never wrote the above but sometime wrote
False,True = 0,1
To me it is hardly a bug to not gratuitously break substantial amounts
of proper code.
>> Back before rebinding 'None' was prohibited, 'is None' was not
>> completely guaranteed either (absent reading the rest of a file to be
>> sure no rebinding would be done).
>>
> And that was a bug too, in this case one that *was* removed in 2.4, I
> believe. Don't have 2.3 lying around just now.
Unlike with True and False, the devs could not think of or find any
proper use case for rebinding None and judged that the new prohibition
would break very little if any code. As far as I know, they were correct.
tjr
> To me it is hardly a bug to not gratuitously break substantial amounts
> of proper code.
>
I quite agree. I take it all back!
>>> Back before rebinding 'None' was prohibited, 'is None' was not
>>> completely guaranteed either (absent reading the rest of a file to be
>>> sure no rebinding would be done).
>>>
>> And that was a bug too, in this case one that *was* removed in 2.4, I
>> believe. Don't have 2.3 lying around just now.
>
> Unlike with True and False, the devs could not think of or find any
> proper use case for rebinding None and judged that the new prohibition
> would break very little if any code. As far as I know, they were correct.
>
Indeed they were.
regards
or slightly less PITAish:
class EqualThing(object):
def __eq__(self, other):
return True
Could be a useful sentinel value in some cases.
>
>
> > I wonder, do newbies actually get the impression from
> somewhere that "is"
> > is a synonym for "=="?
> >
>
>
> Yes. Such questions pop up regularly, and are usually dealt
> with quickly.
>
> >
> >
> >
> >> My own
> >> testing indicates that the former beats the latter by about
> 30% on
> >> average. Not a log for a single instruction but it can add
> up in large
> >> projects.
> >>
> >
> > If you have a "large" project where the time taken to do
> comparisons to
> > None is a significant portion of the total time, I'd be very
> surprised.
> >
> > var is None is a micro-optimization, but that's not why we
> do it. We do
> > it because usually the correct test is whether var *is* None
> and not
> > merely equal to None. Any random object might happen to
> equal None
> > (admittedly most objects don't), but only None is None.
> >
> >
> You don't have that quite right. The only way something can
> *equal*
> None is if it *is* None.
> None is not a value an object can have, but rather it is a
> (singleton)
> object that can be referenced. Setting something *equal* to
> None is
> accomplished by making it refer to the single None object, at
> which
> point it *is* None.
>
> Gary Herron
>
> >
> >
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
> --
> http://mail.python.org/mailman/listinfo/python-list