[Python-ideas] 'Injecting' objects as function-local constants

Steven D'Aprano steve at pearwood.info
Mon Jun 13 09:11:56 CEST 2011

Terry Reedy wrote:
> On 6/12/2011 6:30 PM, Greg Ewing wrote:
>> I'm -1 on any proposal that somehow tries to make the
>> default-argument hack more acceptable.
>> The main reason people still feel the need to use it
>> is that the for-loop is broken, insofar as it doesn't
>> create a new binding for each iteration.
>> The right way to address that is to fix the for-loop,
> Or use closures, which were partly designed to replace default arg use.

Default args are specifically used in at least one use-case where 
closures give the wrong result.

 >>> funcs = [lambda x: x+i for i in range(10)]
 >>> funcs[0].__closure__  # may be different in Python 2.x
(<cell at 0xb7bd8a1c: int object at 0x81b20c0>,)
 >>> funcs[0](42)  # should return 42+0

The usual solution is to *not* use a closure:

 >>> funcs = [lambda x, i=i: x+i for i in range(10)]
 >>> funcs[0].__closure__ is None
 >>> funcs[0](42)
 >>> funcs[9](42)

> This case is quite different from the multiple capture in for-loop case. 
> The OP is simply trying to localize names for speed instead of using 
> module constants, which would otherwise do quite fine and are routinely 
> used in the stdlib.
That's just one use-case. Jan gave two others. Optimizations might be 
common in the stdlib, but it's a hack, and an ugly one.

Function parameters should be kept for actual arguments, not for 
optimizing name look-ups.


More information about the Python-ideas mailing list