[Edu-sig] python versus __python__

2005-10-21 Thread Kirby Urner

Going into my new presentation manager materials (perhaps using the same
Pygame engine I used at OSCON, but as a general purpose module, i.e. not
tied up in that specific content) is the distinction between two kinds of
Python:  Python and __Python__.  

You really get to a new level with Python when you start using its
underunder.  And that occurs, for many, right when they define a first class
(or user type):  in the form of __init__.  __new__ comes even later (a
paradox).

Another fissure defining beginner and advanced:  operator overloading.
That's how it was in C++ books:  we'll get to that later.  Considered an
advanced feature, not even featured in the original Java from Sun.

So a logical course progression might involve doing a lot of non-underunder
stuff at first, exploring but without much introspecting.  Because as soon
as you introspect, ala dir(1), you're into underunder land, and that takes
advanced thinking to negotiate.[1]

Now, just saying there're these two levels isn't to say we can't be up front
about their being there.  I'll tell a class we're tackling Python in two
goes, saving __python__ for Part 2.  I look at Wittgenstein's PI the same
way.  Part 2 is more subtle, and you get more power.  You get to redefine
what you mean by + and *.  Wow.  Snake charmers enter here.

Now there's another way Python gets advanced, which is less about getting
more deeply into Python, and more about getting more deeply into something
else, *using* Python.  That's like when we import a module giving us a wrap
of some external game engine, wherein to construct simulations and so on ala
that project to teach Arabic to soldiers at West Point -- a demo at Pycon
2005 in DC.

So you have different ways of advancing in Python:  into the language more
deeply, to mastery of underunder, metaclasses and beyond; and into foreign
territory, but with Python as your guidebook and phrase book, giving you
confidence amidst all these alien-seeming APIs.  

I suppose poking around under the hood, looking at the C or whatever's
puppeting the Python interpreter, is yet a third direction in which to
advance.  You'll see how underunder is implemented under the hood.  But it
won't be in Python per se, but in Python byte code on a VM (Python-the-agile
skins many a system language -- including in cell phones).

Kirby

[1]

IDLE 1.1  
>>> dir(1)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__',
'__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__',
'__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__',
'__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__',
'__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__',
'__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__',
'__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__str__', '__sub__',
'__truediv__', '__xor__']



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


[Edu-sig] python versus __python__

2005-10-22 Thread Arthur
Kirby -

>PS:  since you've been studying subclassing primitive types using __new__,
>maybe you could show us a user-defined floating point type that reports two
>numbers equal if their absolute value difference is less than e.  Anyone?

My studies on the subject of subclassing the complex type have been quickly 
abandoned - it becoming clear that the fact the .real and .imag are read-only 
defeats the ideas I had for it.  I guess I might have tried harder to see if
one could override that behavior in a subclass, but my decision to move on
is based on the fact that if what I like to think I am pursuing is simplicity, 
changing the  fundamental behavior of a built-in, even if doable, would 
not seem to be a path to it.

But as these dead-end explorations usually do, got me thinking about things not
previously confronted.  Like the simple question of what is "float" 
fundamentally, 
a function - as in float(1) - or a numeric type.  And by subclassing "float", 
is one
subclassing a function or a type. 

Is just some shadowing of a name going on in the netherworld, or are the 
function 
and type more intimately related in that realm?

Us non C programmers look forward to PyPy for the view of the netherworld it 
will
give us.  In truth I expect PyPy to bring a new burst of creative energy to the
Python world, just by opening up the possibility of lower level exploration to 
a wider group of folks.

As the answer to most of the "why Python" questions that we all try to answer
on some technical level, in the end - IMO - boil done to largely that, the 
creative
energy surrounding it.

Perhaps that understanding should provoke me into whining less about the moving
target that Python seems sometimes to be.  Perhaps Guido understands either 
consciously or 
intuitively that less openness to change - with all the downsides of such 
change -
would subvert that essential energy aura in which Python persists.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-21 Thread Arthur
Kirby Urner wrote:

>Going into my new presentation manager materials (perhaps using the same
>Pygame engine I used at OSCON, but as a general purpose module, i.e. not
>tied up in that specific content) is the distinction between two kinds of
>Python:  Python and __Python__.  
>  
>
The ego and the id of it...

is how I sometimes think of it.

>You really get to a new level with Python when you start using its
>underunder.  And that occurs, for many, right when they define a first class
>(or user type):  in the form of __init__.  __new__ comes even later (a
>paradox).
>  
>
Just posted to python-list on this, having found that subclassing 
numeric types is done at the __new__ level, not the __init__ level. 

I see __init__ as everyday waking consciousness, and __new__ inhabiting 
the netherworld.  But making the subconscious conscious leads to good 
mental health. Of which I am th strongest of advocates. And I am trying 
to dredge up __new__ to the conscious level.

>Another fissure defining beginner and advanced:  operator overloading.
>That's how it was in C++ books:  we'll get to that later.  Considered an
>advanced feature, not even featured in the original Java from Sun.
>  
>
This is something I felt comfortable exploring very early on - to the 
extent of having overused it.  I would hate to see you back-end that, as 
I think it is kind of fun to play with.  "let's change the boring old 
rules of math..." kind of thing.

I understand where you are going ,I think, but I would advocate being a 
bit less literal in finding the demarcation at  __xxx__.

You see properties as above ground, and everyday - I still see them as 
convenience for some once-in-a-while-necessary magic calls to __xxx__ 
fairies.

I think the dividing line has something more to do with the degree of 
introspection that one undertakes.

Deeper levels of introspection provokes one into a confrontation with 
one's Pythonic mortality ;)

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-21 Thread Kirby Urner
> This is something I felt comfortable exploring very early on - to the
> extent of having overused it.  I would hate to see you back-end that, as
> I think it is kind of fun to play with.  "let's change the boring old
> rules of math..." kind of thing.
> 

Yes, operator overloading is a big part of my "math through programming"
curriculum.  You want your * and + operators to be "modulo N" for example,
the better to appreciate group theory.  Or we might use * to mean 'compose'
as in:

  >>> def f(x):  return 2*x + 1

  >>> def g(x):  return x**2

  >>> class F(object):

def __init__(self, func):
self.func = func

def __mul__(self, other):
return F(lambda x: self.func(other.func(x)))

def __call__(self,x):
return self.func(x)


  >>> of = F(f)
  >>> og = F(g)
  >>> of(2)
  5
  >>> f(g(2))
  9
  >>> h = of*og
  >>> h(2)
  9
  >>> j = og*of
  >>> j(2)
  25

I think where a lot of kids will first encounter underunder is not in
__init__ but in __name__, as in that "__name__ == '__main__'" trick for
getting scripts to run at the command line, even as they also serve as class
& function repositories for snake charmers in a Python shell.

Kirby

PS:  since you've been studying subclassing primitive types using __new__,
maybe you could show us a user-defined floating point type that reports two
numbers equal if their absolute value difference is less than e.  Anyone?


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Arthur
Arthur wrote:

>Us non C programmers look forward to PyPy for the view of the netherworld it 
>will
>give us.  In truth I expect PyPy to bring a new burst of creative energy to the
>Python world, just by opening up the possibility of lower level exploration to 
>a wider group of folks.
>  
>
So I go the next step, download PyPy, and get at app_complex.py  - which 
is the pypy implementation of the Python complex function, implemented 
in Python - all as advertised.

Which is nicely transparent to someone who can read Python well-enough - 
as advertised.

Not too surprisingly, it uses our friend property to implement the read 
only aspect of .real and .imag, so that by simply commenting out the 
property functions I seem to have what I think I want, the ability to 
work with a complex number object, with the ability to write directly to 
.real and .imag.

Probably from there I rename it from "complex" to "Complex" - I like 
case sensitivity for these kind of reasons - so that I remember I am 
working with the Python function not the built-in function, then inherit 
from it as I was intending to do with the builtin, and then plug it into 
PyGeo.  Sacrificing performance - no doubt - with the upside of running 
it through some paces (the pypy module acknowledges it is not well 
tested, and if there are any issues perhaps they will be uncovered, and 
contributing to pypy in any small way seems worthwhile),  seeing if the  
architecture I had in mind is actually sensible, and seeing if I 
discover why there was a decision to make .real,.imag read only as to 
the builtin.

Yup - pypy is going to change things.

Art

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Arthur
Arthur wrote:

> Arthur wrote:
>
>> Us non C programmers look forward to PyPy for the view of the 
>> netherworld it will
>> give us.  In truth I expect PyPy to bring a new burst of creative 
>> energy to the
>> Python world, just by opening up the possibility of lower level 
>> exploration to a wider group of folks.
>>  
>>
> So I go the next step, download PyPy, and get at app_complex.py  - 
> which is the pypy implementation of the Python complex function, 
> implemented in Python - all as advertised.
>
> Which is nicely transparent to someone who can read Python well-enough 
> - as advertised.

And which, BTW, serves as a nice reference for techniques of operator 
overloading - which I have always found get a bit tricky once one gets 
beyond the simplest form of it.  I had used what I find in Numeric's 
UserArray as my previous reference - nice to have something else to 
study a bit.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Scott David Daniels
Arthur wrote:
> My studies on the subject of subclassing the complex type have been quickly 
> abandoned - it becoming clear that the fact the .real and .imag are read-only 
> defeats the ideas I had for it.
Ahh: complex is (as are bool, int, long, string, and unicode) immutable.
Changing such types to be mutable is "nasty" -- reuse of an immutable is
done by referring to the same object, while reuse of an immutable needs
a copy.  If you do make one of these mutable, be sure to eliminate the
hash function, or you won't be able to have it a key in a dictionary.
Typically immutables are considered "identical" if they have identical
state.  Conceptually there should be no way to tell the difference
between two distinct but equal immutables and the same immutable used
twice.  In fact, you can just check if id(one) == id(other), but that
is "cheating" -- the "no way to tell" avoids precisely this trick.

By the way, before you get too involved in playing with this stuff,
there is a nasty surprise waiting to bite you.  When you are comparing
ids, be sure to compare ids of named things, not expressions.  You might
be surprised to learn: id(math.log(math.pi)) == id(math.log(math.e))!
It is fun to try to figure out why.  I'll post the answer tomorrow if
nobody gets it by then.

> But as these dead-end explorations usually do, got me thinking about things
> not previously confronted.  Like the simple question of what is "float"
> fundamentally,  a function - as in float(1) - or a numeric type.  And by
> subclassing "float", is one subclassing a function or a type. 
 > Is just some shadowing of a name going on in the netherworld, or are
 > the function and type more intimately related in that realm?

If you define a class named PyGeoTriangle, you create new instances with
PyGeoTriangle().  Same with types (especially as we head into
the brave new world of "new-style objects").  The changes in Python are
heading towards a unification of types and classes, but that cannot
fully happen until Python 3.0 (at least).  Why not? -- old-style classes
and new-style classes behave differently under the covers.  So
eventually (and in many cases now), a type name is just a predefined
new-style class name.

New-style classes and standard types can be made to behave quite the
same, but old-style classes cannot.  Unfortunately, some basic parts
of Python (Exception comes to mind) use old-style classes.  Code that
people have written to run with Exception, living in some dark lab in
northern New Jersey (for example), would break if Exception were a
new-style class.  We cannot make the change except when we declare an
"incompatible change".  The reason for making the change to new-style
classes throughout is to simplify Python's design (and the model the
user must have in his head).

> Us non C programmers look forward to PyPy for the view of the netherworld it 
> will
> give us.  In truth I expect PyPy to bring a new burst of creative energy to 
> the
> Python world, just by opening up the possibility of lower level exploration 
> to 
> a wider group of folks.
> 
> As the answer to most of the "why Python" questions that we all try to answer
> on some technical level, in the end - IMO - boil done to largely that, the 
> creative
> energy surrounding it.
> 
> Perhaps that understanding should provoke me into whining less about the 
> moving
> target that Python seems sometimes to be.  Perhaps Guido understands either 
> consciously or 
> intuitively that less openness to change - with all the downsides of such 
> change -
> would subvert that essential energy aura in which Python persists.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Arthur
Scott David Daniels wrote:

>Arthur wrote:
>  
>
>>My studies on the subject of subclassing the complex type have been quickly 
>>abandoned - it becoming clear that the fact the .real and .imag are read-only 
>>defeats the ideas I had for it.
>>
>>
>Ahh: complex is (as are bool, int, long, string, and unicode) immutable.
>Changing such types to be mutable is "nasty" -- reuse of an immutable is
>done by referring to the same object, while reuse of an immutable needs
>a copy.  
>
Getting one's arms around all the practical implications of these issues 
related to mutable, immutable - understanding when one should want to 
retain object  identity, and when one should want to break it, the full 
implications of these decisions,  howto  implement one's intentions - 
is, on one hand - I find, fundamental to getting things to actually 
happen in Python as one intends, and on the other hand , challenging. It 
is the fundamental reason I chafe a bit when Python is described as "easy".

Because I have had  trouble with these issues from day one, it ain't day 
one anymore, I still have some troubles with them and I prefer to think 
that it is challenging over thinking that I am dumb.

I am going down the road of the mutable complex number with my eyes 
(half) open precisely because I want the ability to change the value of 
a complex number object (and it's subclasses), without changing the 
identity of the object.

Is that so wrong ;)

>If you define a class named PyGeoTriangle, you create new instances with
>PyGeoTriangle(). 
>
The connection of what you are saying here to the issue on which I am 
particularly confused  is - well -  confusing, to me.

In Arthur's head there is the numeric type "float", and there is the 
function float() - both built in.  And in Arthur's head, while  
functions are first class objects in Python they are objects of a 
different nature than type in the sense of numeric type.  So in some 
sense what I am not grasping is how class/type unification can be 
inclusive of verb - i.e, float(1) -  and  noun - i.e., type(1.) - 
unification - which in Arthur's head, is something else again.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Kirby Urner
> Kirby
> 
> PS:  since you've been studying subclassing primitive types using __new__,
> maybe you could show us a user-defined floating point type that reports
> two numbers equal if their absolute value difference is less than e.  
> Anyone?
> 

Like this I guess:

 >>> class Fuzzy(float):
 tol = 1e-8
 
   def __new__(cls, arg=0.0):
return float.__new__(cls, arg)

 def __eq__(self, other):
if abs(self-other)>> j = Fuzzy(10)
 >>> type(j)
 

 >>> k = Fuzzy(10.1)

 >>> j == k
 True

 >>> k = Fuzzy(10.01)

 >>> j == k
 False

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Scott David Daniels
Kirby Urner wrote:
>>Kirby
>>
>>PS:  since you've been studying subclassing primitive types using __new__,
>>maybe you could show us a user-defined floating point type that reports
>>two numbers equal if their absolute value difference is less than e.  
>>Anyone?
>>
> 
Fuzzy redone a breath:
class Fuzzy(float):
 tol = 1e-8
 def __new__(cls, arg=0.0):
 return float.__new__(cls, arg)
 def __eq__(self, other):
 return abs(self - other) < self.tol
> ...

Here's the problem:
Your notion of equality is not transitive.  That's tough -- it
invalidates the assumptions of the float type (and all basic types).
Also, you didn't tweak hash, so a dictionary with these things in them
would not find entries that turn out to be equal.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Kirby Urner
> Here's the problem:
> Your notion of equality is not transitive.  That's tough -- it
> invalidates the assumptions of the float type (and all basic types).
> Also, you didn't tweak hash, so a dictionary with these things in them
> would not find entries that turn out to be equal.
> 
> --Scott David Daniels
> [EMAIL PROTECTED]

Yes, good tweak, and fair warnings (GvR warned me earlier).  

Fuzzy is no doubt pretty useless, plus I solved my earlier problem a
different way.

This thread has been helpful nonetheless.  I've learned more __python__.

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-23 Thread Scott David Daniels
Arthur wrote:
> Scott David Daniels wrote:
> ... 
> Getting one's arms around all the practical implications of these issues 
> related to mutable, immutable - understanding when one should want to 
> retain object  identity, and when one should want to break it, the full 
> implications of these decisions,  howto  implement one's intentions - 
> is, on one hand - I find, fundamental to getting things to actually 
> happen in Python as one intends, and on the other hand , challenging. It 
> is the fundamental reason I chafe a bit when Python is described as "easy".
Ah, but you are concentrating on fundamental issues of language design
which are, in fact, subtle.  Normally the user of a language simply
accepts the determination of the designer about what is mutable and
what is not, and goes on from there.  I think these issues are indeed
fascinating, but they are issues of language design, not even issues
for the __python__ class.  Python allows you to play with these issues
in your own classes, few other languages allow you that freedom.

> Because I have had  trouble with these issues from day one, it ain't day 
> one anymore, I still have some troubles with them and I prefer to think 
> that it is challenging over thinking that I am dumb.
Well, you are right.

> I am going down the road of the mutable complex number with my eyes 
> (half) open precisely because I want the ability to change the value of 
> a complex number object (and it's subclasses), without changing the 
> identity of the object.
In the first Fortran (and for a number of versions later), you called
"subroutines" with all arguments "by reference."  There were people
who would abuse this ability to change constants (which were shared
across a single "compilation unit") to find compact ways to alter
things that were not properly variables.  This brings new meaning
to "1+1=4 for sufficiently large values of 1".

>>If you define a class named PyGeoTriangle, you create new instances with
>>PyGeoTriangle().
> 
> The connection of what you are saying here to the issue on which I am 
> particularly confused  is - well -  confusing, to me.

I'm trying to point out that you understand perfectly that some things
are both objects and callable; you just don't realize that you do.  The
most obvious example is a class, while the second (and far less) obvious
is an instance of a class with a __call__ method.

In the case of a class that you have defined, you can use the class name
itself in calls to things like "isinstance,"

> In Arthur's head there is the numeric type "float", and there is the 
> function float() - both built in.  And in Arthur's head, while  
> functions are first class objects in Python they are objects of a 
> different nature than type in the sense of numeric type.  

> So in some sense what I am not grasping is how class/type unification 
> can be inclusive of verb - i.e, float(1) -  and  noun - i.e., type(1.) 
> - unification - which in Arthur's head, is something else again.
The magic trick of class / type unification is: we both need to name
types (they must have existence as objects) for use in some functions,
and we need to provide constructors for instances of that type.  This
is the same situation we are in about classes.  The class situation is
resolved by making "special" methods that get invoked when the class is
used to call


--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-24 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:edu-sig-
> [EMAIL PROTECTED] On Behalf Of Kirby Urner
> Sent: Sunday, October 23, 2005 8:30 PM
> To: 'Scott David Daniels'; edu-sig@python.org
> Subject: Re: [Edu-sig] python versus __python__
> 
> Fuzzy is no doubt pretty useless, plus I solved my earlier problem a
> different way.
> 
> This thread has been helpful nonetheless.  I've learned more __python__.

Funny the connection.

We're both going off doing useless things with numeric builtins, and playing
around to try to solve some perceived "identity crisis".  Just very
different  kinds of ones.

Art 




___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-24 Thread Scott David Daniels
Scott David Daniels wrote:
> By the way, before you get too involved in playing with this stuff,
> there is a nasty surprise waiting to bite you.  When you are comparing
> ids, be sure to compare ids of named things, not expressions.  You might
> be surprised to learn: id(math.log(math.pi)) == id(math.log(math.e))!
> It is fun to try to figure out why.  I'll post the answer tomorrow if
> nobody gets it by then.

With CPython, expressions, once used and dereferenced, recycle their
objects.  If you don't hold a reference to the value created by
calculating the log of pi, it will get recycled once id is done
with is arg.  The available storage is lying around when log(e)
is calculated and so is reused.  Such things don't happen when
working with small integers, because Python caches them to save
some creation time.

So,
 id(math.pi + 1.0) == id(29. / 7.)

but then again:
 id(math.pi + 5280.0) == id(1. / 9.)

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-25 Thread Beni Cherniavsky
On Mon, 2005-10-24 at 20:24 -0700, Scott David Daniels wrote:
> With CPython, expressions, once used and dereferenced, recycle their
> objects.  If you don't hold a reference to the value created by
> calculating the log of pi, it will get recycled once id is done
> with is arg.  The available storage is lying around when log(e)
> is calculated and so is reused.  Such things don't happen when
> working with small integers, because Python caches them to save
> some creation time.
> 
> So,
>  id(math.pi + 1.0) == id(29. / 7.)
> 
> but then again:
>  id(math.pi + 5280.0) == id(1. / 9.)
> 
Neat :-)

Of course, the proper way to compare object identity is not the
__low_level__ `id()` function but the ``is`` operator:

>>> (math.pi + 1.0) is (29. / 7.)
False
>>> int('99') is int('99') # small integer
True
>>> int('100') is int('100') # big integer
False

[``is`` works properly because both expressions are evaluted before the
``is`` operator is evaluted and only then the 2 values are
garbage-collected.  With `id()`, the 2 values could be reclaimed
immediately because only the address is needed for the ``==``
comparison.  The fact that `id(foo)` does not reference `foo` is the #1
source of confusion regarding `id()`.]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] python versus __python__

2005-10-26 Thread Scott David Daniels
Beni Cherniavsky wrote:
> On Mon, 2005-10-24 at 20:24 -0700, Scott David Daniels wrote:
> 
> Of course, the proper way to compare object identity is not the
> __low_level__ `id()` function but the ``is`` operator:
> 
(math.pi + 1.0) is (29. / 7.)
> 
> False
> 
int('99') is int('99') # small integer
> 
> True
> 
int('100') is int('100') # big integer
> 
> False
> 
> [``is`` works properly because both expressions are evaluted before the
> ``is`` operator is evaluted and only then the 2 values are
> garbage-collected.  With `id()`, the 2 values could be reclaimed
> immediately because only the address is needed for the ``==``
> comparison.  The fact that `id(foo)` does not reference `foo` is the #1
> source of confusion regarding `id()`.]
That won't save you from surprises when walking in subtle territory.

For example:  # Distributive law
 >>> -(-3 - 7) is (- -3) - -7
True

But:
 >>> -(3 + 7) is -3 - -7
False

The difference is the aforementioned caching trick -- small positive
(and a few negative) integers are cached, the exact range is, I think
-5 : 100, but it is subject to change and should _not_ be remembered
(Python is free to change the number at any time; caching is an
optimization, not meant to affect the meaning of the language).

In general the "is" operator is asking about internals you should seldom
be poking around inside (playing with magic) except for the incantation
"is None" and "is not None" since there is one and only one None.  There
are, of course, times when you are concerned about "exactly this object"
and those times are when is is proper, (and id(obj) might well be a
perfectly fine value supplying a total order on such objects).

The main reason I am belaboring the point is the recent mutable /
immutable discussion: you should never concern yourself with the
identity of an immutable; they are "values" to be compared using
equality or ordering comparisons.  Two immutables built the same way
should be indistinguishable from two references to the same immutable
in properly written code.  You need immutables for dictionary keys,
because (in the implementation) structure is built based on values
of the keys.  If the values changed by mutating, your structure
would no longer reflect the values it contains (so some data would
become unreachable).
 storage = {3+4j : 1, 4+3j : 2}
 Suppose you negated the imaginary part of the object which is the
key to the value 1.

  What should storage[3+4j] (where 3+4j is freshly calculated) return?
  What should storage[3-4j] (where 3-4j is freshly calculated) return?

Such problems are not so much implementation issues (although they do
reveal the implementation) as problems with the definition of the
language.  That's why this is subtle territory.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig