"/a" is not "/a" ?

  • Thread starter Emanuele D'Arrigo
  • Start date
C

Carl Banks

But since newbies are always falling into this trap, it is still a good
rule to say:

  Newbies:  Never use "is" to compare immutable types.

No it isn't, it's asinine advice that's not even a simpllified truth,
it's just a lie.

Newbies who don't understand the difference between "==" and "is"
should not be using "is", for any object, immutable or mutable, aside
from None (which, whether you like it or not, is idomatic Python).

Everyone who's learned the difference between equality and same
identity, including experts, should be using "is" only to test if some
object is the same object they created themselves, or is an object
guaranteed by a library or the langauge to never change, irrespective
of whether the object is mutable or not.

At no point on the learning curve is the distinction of when to use
"is" or not ever mutability.


Carl Banks
 
P

Paul Rubin

Steven D'Aprano said:
It is never
correct to avoid using "is" when you need to compare for identity.

When is it ever necessary to compare for identity?
 
S

Steven D'Aprano

Of course, the more complex the objects you are comparing the
stronger the recommendation agaist using 'is' to compare two objects.

Why is there so much voodoo advice about "is"? Is object identity really
such a scary concept that people are frightened of it?

Mutable versus immutable is irrelevant. The complexity of the object is
irrelevant. The phase of the moon is irrelevant. The *only* relevant factor
is the programmer's intention:

If you want to test whether two objects have the same value (equality), the
correct way to do it is with "==".

If you want to test whether two objects are actually one and the same
object, that is, they exist at the same memory location (identity), the
correct way to do it is with "is".

If you find it difficult to think of a reason for testing for identity,
you're right, there aren't many. Since it's rare to care about identity, it
should be rare to use "is". But in the few times you do care about
identity, the correct solution is to use "is" no matter what sort of object
it happens to be. It really is that simple.
 
R

Robert Kern

When is it ever necessary to compare for identity?

Caches of arbitrary objects.

When checking if an object (which may be have an arbitrarily perverse __eq__) is
None.

Or a specifically constructed sentinel value.

Checking for cycles in a data structure that defines __eq__.

--
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
 
S

Steven D'Aprano

Gary said:
Nonsense.  Show me "newbie" level code that's buggy with "==" but
correct with "is".

What's "newbie" level code? What does that even *mean*? There's no sandbox
for newbies to play in -- their code runs in the same environment as code
written by experts. Newbies can import modules written by experts and use
their code: any object, no matter how complex, might find itself imported
and used by a newbie. Sometimes code written by newbies might even find its
way into code used by experts.

But regardless of that, the point is, what's your motivation in giving
advice to newbies? Do you want them to learn correct coding techniques, or
to learn voodoo programming and superstition? If you want them to learn
correct coding, then teach them the difference between identity and
equality. If you want them to believe superstitions, then continue telling
them never to use "is" without qualifications.
 
S

skip

Steven> Mutable versus immutable is irrelevant. The complexity of the
Steven> object is irrelevant. The phase of the moon is irrelevant. The
Steven> *only* relevant factor is the programmer's intention:

Which for a new user not familiar with the differing concepts of "is" and
"==" can lead to mistakes.

Steven> If you find it difficult to think of a reason for testing for
Steven> identity, you're right, there aren't many. Since it's rare to
Steven> care about identity, it should be rare to use "is". But in the
Steven> few times you do care about identity, the correct solution is to
Steven> use "is" no matter what sort of object it happens to be. It
Steven> really is that simple.

Right. Again though, when newcomers conflate the concepts they can deceive
themselves into thinking "is" is just a faster "==".

Skip
 
S

Steven D'Aprano

Steven> Mutable versus immutable is irrelevant. The complexity of the
Steven> object is irrelevant. The phase of the moon is irrelevant. The
Steven> *only* relevant factor is the programmer's intention:

Which for a new user not familiar with the differing concepts of "is" and
"==" can lead to mistakes.

Right. And for newbies unfamiliar with Python, they might mistakenly think
that ^ is the exponentiation operator rather than **.

So what do we do? Do we teach them what ^ actually is, or give them bad
advice "Never call ^" and then watch them needlessly write their own
exponentiation function?

Do we then defend this terrible advice by claiming that nobody needs
exponentiation? Or that only experts need it? Or that it's necessary to
tell newbies not to use ^ because they're only newbies and can't deal with
the truth?

No, of course not. But that's what some of us are doing with regard to "is".
Because *some* newbies are ignorant and use "is" for equality testing, we
patronisingly decide that *all* newbies can't cope with learning what "is"
really is for, give them bad advice, and thus ensure that they stay
ignorant longer.

Steven> If you find it difficult to think of a reason for testing for
Steven> identity, you're right, there aren't many. Since it's rare to
Steven> care about identity, it should be rare to use "is". But in the
Steven> few times you do care about identity, the correct solution is
to Steven> use "is" no matter what sort of object it happens to be. It
Steven> really is that simple.

Right. Again though, when newcomers conflate the concepts they can
deceive themselves into thinking "is" is just a faster "==".

Then teach them the difference, don't teach them superstition.
 
A

alex23

Right.  Again though, when newcomers conflate the concepts they can deceive
themselves into thinking "is" is just a faster "==".

But _you_ only _just_ stated "It does have some (generally small)
performance ramifications as
well" and provided timing examples to show it. Without qualification.

And you're wondering why these mythical newcomers might be confused...
 
S

Steven D'Aprano

Paul said:
When is it ever necessary to compare for identity?

Is that a trick question? The obvious answer is, any time you need to.

The standard library has dozens of tests like:

something is None
something is not None

Various standard modules include comparisons like:

if frame is self.stopframe:
if value is not __UNDEF__:
if b is self.exit:
if domain is Absent:
if base is object:
if other is NotImplemented:
if type(a) is type(b):

although that last one is probably better written using isinstance() or
issubclass(). I have no doubt that there are many more examples.

Comparing by identity are useful for interning objects, for testing that
singletons actually are singletons, for comparing functions with the same
name, for avoiding infinite loops while traversing circular data
structures, and for non-destructively testing whether two mutable objects
are the same object or different objects.
 
P

Paul Rubin

alex23 said:
But _you_ only _just_ stated "It does have some (generally small)
performance ramifications as
well" and provided timing examples to show it. Without qualification.

The performance difference can be large if the objects are (for
example) long lists.
 
A

Albert Hopkins

The performance difference can be large if the objects are (for
example) long lists.

I would think (not having looked) that the implementation of == would
first check for identity (for performance reasons)... but then that lead
me to ask: can an object be identical but not equal to itself?
 
A

Albert Hopkins

I would think (not having looked) that the implementation of == would
first check for identity (for performance reasons)... but then that lead
me to ask: can an object be identical but not equal to itself?

.... answered my own question


class Foo:
def __eq__(self, b):
return False
--> True
--> False
 
S

Steven D'Aprano

Albert said:
I would think (not having looked) that the implementation of == would
first check for identity (for performance reasons)...

For some types, it may. I believe that string equality testing first tests
whether the two strings are the same string, then tests if they have the
same hash, and only then do a character-by-character comparison. Or so I've
been told.
can an object be identical but not equal to itself?

Yes. Floating point NANs are required to compare unequal to all floats,
including themselves. It's part of the IEEE standard.

Python doesn't assume that == must mean equality. If, for some bizarre
reason you want to define == to mean something completely different, then
you can define x == x to return anything you like for your class.
 
M

Marc 'BlackJack' Rintsch

That is absolutely wrong:

False

What should this example show? And where's the singleton here? BTW:

In [367]: a = 2 ^ 100

In [368]: b = 2 ^ 100

In [369]: a == b
Out[369]: True

In [370]: a is b
Out[370]: True

Ciao,
Marc 'BlackJack' Rintsch
 
P

Paul Rubin

Marc 'BlackJack' Rintsch said:
What should this example show? And where's the singleton here? BTW:

I misunderstood at first what you meant by "singleton". Sorry.
 
L

Lie Ryan

Steven said:
For some types, it may. I believe that string equality testing first tests
whether the two strings are the same string, then tests if they have the
same hash, and only then do a character-by-character comparison. Or so I've
been told.


Yes. Floating point NANs are required to compare unequal to all floats,
including themselves. It's part of the IEEE standard.

btw, have anybody noticed that the subject line "/a" is not "/a" is
actually False.
True
 
M

Mel

Emanuele said:
Gary, thanks for your reply: your explanation does pretty much answer
my question. One thing I can add however is that it really seems that
non-alphanumeric characters such as the forward slash make the
difference, not just the number of characters. I.e.

(Actually, we had this thread last week.) It's a question of strings that
might be Python names. Every line of code that looks up a name in a
namespace (e.g. global symbols, instance attributes, class attributes, etc.)
needs a string containing the name. This optimization keeps Python data
space from filling up with names. The same thing happens with small,
common, integers.
[ ... ]
I just find it peculiar more than a nuisance, but I'll go to the
blackboard and write 100 times "never compare the identities of two
immutables". Thank you all!

The rule is to know the operations, and use the ones that do what you want
to do. `is` and `==` don't do the same thing. Never did, never will.

<sarcasm>
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.False

At this point, someone says 'Eek'. But why? `+` and `-` never were the
same operation, regardless of a coincidence or two.
</sarcasm>

Mel.
 
M

Mel

wrote:
When is it ever necessary to compare for identity?

Ho-hum. MUDD game.

def broadcast (sender, message):
for p in all_players:
if p is not sender:
p.tell (message) # don't send a message to oneself


Mel.
 
E

Emanuele D'Arrigo

For b), the rationale is that such string literals
in source code are often used to denote names, e.g.
for getattr() calls and the like. As all names are interned,
name-like strings get interned also.

Thank you Martin, and all others who have responded, I have a much
better picture of the whole issue now. Much appreciated.

Manu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top