From: Steven D'Aprano on
On Fri, 06 Aug 2010 17:20:30 +0000, Peter Pearson wrote:

> On Fri, 06 Aug 2010 15:37:04 +0200, Stefan Schwarzer wrote: [snip]
>> I can imagine a case where you might want to compare a string with
>> `is`:
>>
>> FORWARD = "forward"
>> BACKWARD = "backward"
[...]
>> Actually, I've never seen such a use, as far as I remember. What do
>> other people here think? Is the code above, which compares strings with
>> `is`, bad style, and if yes, why? How would you write the code instead?
>
> Hey, that's a cute example, but . . . what a trap! Is it possible to
> document the use-the-object-not-the-string requirement loudly enough
> that people won't get caught?

Nope. People don't read documentation :)

That's why I prefer to test for human-readable constants using equality,
so if the caller prefers to call func(x, "forward") instead of func(x,
FORWARD) it will still work.

Or I use

FOWARD = object()
BACKWARDS = object()

and force them to use my constants.



--
Steven
From: Steven D'Aprano on
On Fri, 06 Aug 2010 05:28:40 -0700, DG wrote:

> I've always thought of it as you don't compare strings with "is", you
> *should* use == The reasoning is that you don't know if that string
> instance is the only one in memory.

This is excellent advice. I won't say that there is "never" a use-case
for testing strings for identity, but I can't think of one that isn't
contrived and artificial.


> I've heard as an implementation
> detail, since strings are immutable, that Python will only create one
> actual instance and just assign new references to it (your first x is y
> example), but to compare equality it just makes sense to use "==", not
> to ask if it is the same object in memory. Plus, I believe the "=="
> operator will check if the variables point to the same object.

Yes, that is an optimization that CPython performs. Other implementations
may do different, but the optimization is so obvious and so cheap that I
would be shocked if any of the major implementations fail to do so.


> Using is/is not with None works well, because I believe there will
> always only be 1 None object.

Yes, that is correct, but there's also a semantic difference. Generally,
when testing for None, you actually want None and not some look-alike
that merely tests equal to None. You want to "accept no substitutes", and
so an identity test is necessary.



--
Steven
From: Steven D'Aprano on
On Fri, 06 Aug 2010 15:37:04 +0200, Stefan Schwarzer wrote:

>> Plus, I believe the
>> "==" operator will check if the variables point to the same object.
>
> No, that's what `is` is for.

Actually, yes, equality is implemented with a short-cut that checks for
identity first. That makes something like:

s = "abc"*1000*1000*10
s == s

nice and quick, as Python can immediately recognise that a string is
always equal to itself without having to walk the entire string comparing
each character with itself.



--
Steven
From: Steven D'Aprano on
On Fri, 06 Aug 2010 11:42:39 +0200, Jean-Michel Pichavant wrote:

> Steven D'Aprano wrote:
>> On Thu, 05 Aug 2010 12:07:53 -0400, wheres pythonmonks wrote:
>>
>>> P.S. Sorry for the top-post -- is there a way to not do top posts from
>>> gmail? I haven't used usenet since tin.
>>>
>> Er, surely you can just move the cursor before you start typing???
>>
> CTRL+END will bring the cursor at the end of the file (for most the the
> mail clients).

Bottom-posting is just as annoying as top-posting, except for very short
posts like this. Posting in-line, where you trim the excess quoting to
leave enough to give context, is most recommended.


--
Steven
From: Gregory Ewing on
Ethan Furman wrote:

> Instead of using 'is' use '=='. Maybe not as cute, but definitely more
> robust!

It's also just as efficient if you use strings that
resemble identifiers, because they will be interned,
so the comparison will end up just doing an indentity
test anyway.

--
Greg