[Edu-sig] Python for Fun

Chris Meyers cmeyers@guardnet.com
Fri, 25 May 2001 14:31:39 -0800


05/25/2001 1:55:29 PM, Kirby Urner <pdx4d@teleport.com> wrote:
Hi Kirby,
 
 We're still on Python 1.5.3 mainly because we have so much code in 
running systems that upgrading involves a lot of regression 
testing. Try for this summer for sure. Lots of stuff out there that 
assumes 2.0 as a base. Zope, Vpython, wxPython, etc. A year ago we 
upgraded from 3.0 and had some glitches - mostly with comparisons 
where one value was None.
 

>Just for fun:  tweaking logic.py Connector class with 2.1 idioms:
>
>    def connect (self, inputs) :
>        if type(inputs) != type([]) : inputs = [inputs]
>        self.connects += inputs  # <-- here
>
This is a nice new feature (+= etc.). Does it save time and 
evaluate the left hand address only once? Or is it just syntactic 
sugar? If the calculation is complex, it can make a real difference 
in program speed. Like

          array[n][nextSlot(whatever)] += 1
Or in our case we are very often incrementing (or the like) an 
object attribute, which is a really a dict lookup. Don't want to do 
the lookup twice.

>    def set (self, value) :
>        if self.value == value : return      # Ignore if no change
>        self.value = value
>        if self.activates : self.owner.evaluate()
>        if self.monitor :
>            print "Connector %s-%s set to %s" % \
>                  (self.owner.name,self.name,self.value)
>        [con.set(value) for con in self.connects]  # <-- and here
>
This should also save time, I would think, since the list is not 
constantly resized? Can't test it. Don't work on 1.5.3
>
>Could also go:
>
>   self.connects.extend(inputs)  (is that 1.5 or later?)
>
Is this actually different from .append ?
>
>I find it interesting that you can define lists simply for 
>their side-effects, with the list itself saved nowhere.  Indeed,
>you can stick [1,2,3] (no assignment to a variable) anywhere 
>a method and nothing happens -- __repr__ isn't triggered 
>except at the command line.
>
That's kind of cool. I had never tried it. Replace 1,2,3 with 
function calls and off they go, left to right. This reminds me of 
the old Lisp "PROG" that would evaluate its arguments just for the 
side effects.

>I did have
>
>  map(lambda con: con.set(value), self.connects)
>
>which makes use of nested scopes (value in lambda is getting a 
>pointer from the surrounding method), but list comprehension 
>doesn't see this as a case of scope nesting i.e. variables 
>within the brackets are locally scoped already.
>

I tried this and it seemed to work
>>>
>>> class con :
...     def __init__ (self) :
...             self.x = 5
...     def prnt (selfi,c) :
...             print self.x + c
...
>>> a = con()
>>> b = [a,a,a]
>>> map(lambda x: x.prnt(4), b)
9
9
9
[None, None, None]
>>>
Speaking of scoping. If you get around to Lisp in Python, there's a 
section on dynamic scoping with an example.

Chris