[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