[Python-Dev] closure semantics

Guido van Rossum guido at python.org
Wed Oct 22 13:57:18 EDT 2003


[Samuele]
> why exactly do we want write access to outer scopes?
>> for completeness, to avoid the overhead of introducing a class here
> and there, to facilitate people using Scheme textbooks with Python?

Probably the latter; I think Jeremy Hylton does know more Scheme than
I do. :-)
> so far I have not been missing it,
>> I don't find:
>> def accgen(n):
> def acc(i):
> global n in accgen
> n += i
> return n
> return acc
>> particulary more compelling than:
>> class accgen:
> def __init__(self, n):
> self.n = n
>> def __call__(self, i):
> self.n += i
> return self.n

Some people have "fear of classes". Some people think that a
function's scope can be cheaper than an object (someone should time
this).
Looking at the last example in the itertools docs:
 def tee(iterable):
 "Return two independent iterators from a single iterable"
 def gen(next, data={}, cnt=[0]):
 dpop = data.pop
 for i in count():
 if i == cnt[0]:
 item = data[i] = next()
 cnt[0] += 1
 else:
 item = dpop(i)
 yield item
 next = iter(iterable).next
 return (gen(next), gen(next))
This would have been clearer if the author didn't have to resort to
representing his counter variable as a list of one element. Using
'global* x' to mean 'find x in an outer scope', and also moving data
into the outer scope, again to emphasize that it is shared between
multiple calls of gen() without abusing default arguments, it would
become:
 def tee(iterable):
 "Return two independent iterators from a single iterable"
 data = {}
 cnt = 0
 def gen(next):
 global* cnt
 dpop = data.pop
 for i in count():
 if i == cnt:
 item = data[i] = next()
 cnt += 1
 else:
 item = dpop(i)
 yield item
 next = iter(iterable).next
 return (gen(next), gen(next))
which is IMO more readable.
But in 2.4 this will become a real object implemented in C. :-)
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /