Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

Python Basic Doubt

 

 

First page Previous page 1 2 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded


rosuav at gmail

Aug 10, 2013, 9:51 PM

Post #26 of 31 (17 views)
Permalink
Re: Python Basic Doubt [In reply to]

On Sun, Aug 11, 2013 at 5:29 AM, Gary Herron
<gary.herron [at] islandtraining> wrote:
> A beginner, on his first program or two, can understand 1, and perhaps
> parrot 2 without understanding (or needing to). But the step from there to
> 3 is huge. It's folly to dump that on a first-time programmer. (It's
> probably even folly to dump that on a seasoned programmer just starting in
> Python. I still remember not understanding the explanation for "is" when I
> first read it. And it continued to make no sense until I had enough
> experience to understand the difference betwen C/C++ assignment to variables
> and Python's binding of variables.)

See, that's where the problem is. You will never grok the difference
between == and is if you're still thinking about C variables. (Though
you *might* be able to explain it by talking solely about char* and
the way two C strings can be the same but stored at different places
in memory. But that would be unhelpful most of the time.)

This is important *early* reading for a new Python programmer:

http://mail.python.org/pipermail/tutor/2010-December/080505.html

Note that it was originally posted on python-tutor, so it was
definitely aimed at the inexperienced.

> On 08/10/2013 08:43 PM, Chris Angelico wrote:
> Granted, English is a poor litmus test for code. But in this
> particular example, we're talking about immutable types (simple
> integers), where value and identity are practically the same. A Python
> implementation would be perfectly justified in interning *every*
> integer, in which case the 'is' would work perfectly here. The
> distinction between the two is important when the objects are mutable
> (so they have an identity that's distinct from their current values).
>
>
> Granted. But please note: There is *nothing* in that sentence which is fit
> for a beginner programmer. ... "immutable", "value/identity", "interning"
> ... In one ear and out the other. :-)

Right. This isn't my explanation of 'is' and '=='; it's my explanation
of why it's important to HAVE an explanation of the aforementioned. :)
Though the difference between value and identity is significant and
important, and mutability is bound to crop up fairly early on; so
really, it's only the concept of interning that would be really
advanced.

ChrisA
--
http://mail.python.org/mailman/listinfo/python-list


steve+comp.lang.python at pearwood

Aug 11, 2013, 1:03 AM

Post #27 of 31 (17 views)
Permalink
Re: Python Basic Doubt [In reply to]

On Sat, 10 Aug 2013 17:42:21 -0700, Gary Herron wrote:

> But for each of your examples, using "==" is equivalent to using "is".
> Each of
> if something == None
> if device == _not passed
> if device != None
> would all work as expected. In none of those cases is "is" actually
> needed.


... def __eq__(self, other):
... return True
...
True

Oops.

Now Weird is, naturally, weird. But classes may have a legitimate reason
to claim to be equal to None, or at least the creator of the class may
believe he has a legitimate reason. It's not forbidden, therefore you
have to assume somebody will do so.

But more importantly, in checking whether some value is a sentinel, the
*intention* of the code is to check that the value *actually is* the
sentinel, not merely that it happens to be equal to the sentinel. To give
an analogy: when you hand the codes to the nuclear arsenal to the
President, you want to make sure that it actually *is* the President, not
some impostor who merely looks and sounds like him.

"value == None" not only risks doing the wrong thing if passed some weird
object, but it fails to match the intention of the code. Whereas "value
is None" is idiot-proof (it cannot fail -- short of hacking the compiler,
you cannot change the meaning of either "is" or "None"), it matches the
intention of the code, and therefore is clearer, more explicit, and more
idiomatic. And as a bonus, it's faster too. But speed is not why you
should use it. You should use it because it matches the intention of the
code. You don't want to test for some arbitrary person who happens to
look like the President, you want to test for the President himself, and
nobody but the President.

On the other hand, code like "x is 42.9" does not match the intention of
the code, and is likely to fail. "is" is not a synonym for "==".
Conflating them is a bad thing, whether you use "is" to check for
equality or "==" to check for identity.


> Given that, and the implementation dependent oddities, I still believe
> that it is *highly* misleading to teach a beginner about "is".

Careful -- it's not "is" which is implementation-dependent. The "is"
operator works the same way in every Python implementation. What differs
are the rules for when new instances are created from literals.


> Here's a challenge: What is the simplest non-contrived example where an
> "is" comparison is *required*. Where substitution of an "==" comparison
> would cause the program to fail or be significantly less efficient? (I'm
> not including the nearly immeasurably small timing difference between
> v==None and v is None.)

Easy-peasey. Test code often relies on "is" to check object identity.
Occasionally such comparisons work there way into production code, but
they're common in tests.

In one of my test suites, I have code that verifies that a certain
function which takes a list as argument does not modify it in place. So
my unit test looks like this:


def testNoInPlaceModifications(self):
# Test that the function does not modify its input data.
data = self.prepare_data()
assert len(data) != 1 # Necessary to avoid infinite loop.
assert data != sorted(data)
saved = data[:]
assert data is not saved # <<<=== LOOK HERE ===
_ = self.func(data)
self.assertListEqual(data, saved, "data has been modified")


Note that is would be *wrong* to replace the "is not" comparison with not
equal to. The list and its copy are, in fact, equal. If they aren't
equal, the test fails.

In this case, the assertions are there as verifiable comments. They
communicate to the reader, "These are the assumptions this test relies
on", except unlike comments, if the assumptions are violated, the test
will fail. Unlike comments, they cannot ever get out of date.



--
Steven
--
http://mail.python.org/mailman/listinfo/python-list


steve+comp.lang.python at pearwood

Aug 11, 2013, 1:07 AM

Post #28 of 31 (15 views)
Permalink
Re: Python Basic Doubt [In reply to]

On Sat, 10 Aug 2013 20:21:46 -0700, Gary Herron wrote:

> Our knee-jerk reaction to beginners using "is" should be:
> Don't do that! You almost certainly want "==". Consider "is" an
> advanced topic.
>
> Then you can spend as much time as you want trying to coach them into an
> understanding of the precise details. But until they have that
> understanding, they are well served by a rule-of-thumb that says:
> Use "==" not "is" for comparisons.

"...except for comparing to None, where 99.99% of the time you do
actually want an identity comparison."

This can lead into a more detailed explanation for why you should choose
one over the other, or the incurious newbie could take it is something to
be learned by rote. I have no problem with telling newbies that there is
a reason for this apparently arbitrary rule, but they don't need to learn
it *right now* if they don't want.

In any case, the rule can include "When in doubt, use equals". I'm good
with that :-)


--
Steven
--
http://mail.python.org/mailman/listinfo/python-list


steve+comp.lang.python at pearwood

Aug 11, 2013, 1:29 AM

Post #29 of 31 (16 views)
Permalink
Re: Python Basic Doubt [In reply to]

On Sat, 10 Aug 2013 16:42:22 -0400, Roy Smith wrote:

> In article <mailman.439.1376166663.1251.python-list [at] python>,
> Dennis Lee Bieber <wlfraed [at] ix> wrote:
>
>> Because id(n) is not giving you the address of the NAME. It is giving
>> you the address of the "10"
>
> Actually, it is giving you the id of the int(10) object. Maybe it's an
> address, maybe it's not. Only your implementation knows for sure.

/steve cheers from the audience

Thank you for mentioning this. Using Jython:

>>> x = 10
>>> id(x)
1


And using IronPython:

>>> x = 10
>>> id(x)
43


"id" does not stand for "memory address". It stands for "identity".


--
Steven
--
http://mail.python.org/mailman/listinfo/python-list


jarabal at gmail

Aug 11, 2013, 9:58 AM

Post #30 of 31 (13 views)
Permalink
Re: Python Basic Doubt [In reply to]

Thanks to all for your answers,

I guess it is more flexible with isinstance (the duck test :)
I'm going to change the type checks.

Respect to the "Names starting and ending with double-underscore".
I don't know how to get the name of a classe without them.
obj.__class__.__name__

Thanks.
--
Xavi
--
http://mail.python.org/mailman/listinfo/python-list


steve+comp.lang.python at pearwood

Aug 11, 2013, 6:08 PM

Post #31 of 31 (10 views)
Permalink
Re: Python Basic Doubt [In reply to]

On Sun, 11 Aug 2013 18:58:25 +0200, Xavi wrote:

> Respect to the "Names starting and ending with double-underscore". I
> don't know how to get the name of a classe without them.
> obj.__class__.__name__

I didn't say you should *never* use them, but most of the time, you don't.

However type(obj).__name__ should be better.


--
Steven
--
http://mail.python.org/mailman/listinfo/python-list

First page Previous page 1 2 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.