[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
51
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
True
>>> funcs[0](42)
42
>>> funcs[9](42)
51
> 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.
--
Steven
More information about the Python-ideas
mailing list