[Python-ideas] Tweaking closures and lexical scoping to include the function being defined
Guido van Rossum
guido at python.org
Thu Sep 29 04:54:26 CEST 2011
On Wed, Sep 28, 2011 at 5:41 PM, Jim Jewett <jimjjewett at gmail.com> wrote:
> On Wed, Sep 28, 2011 at 12:12 AM, Terry Reedy <tjreedy at udel.edu> wrote:
>> ... Python has a simple rule: header expressions (for default args) are
>> evaluated one-time when the function is defined; body expressions are
>> evaluated (perhaps) each time when the function is called.
> Note that this also matches indentation, since decorators are indented
> with the header, rather than with the body.
>> If people understand this and do not fight it, they are not surprised that
>> mutating a once-defined default arg mutates it, nor that defining a function
>> inside a loop magically causes define-time binding of names in the body.
> Though they may still be surprised in the opposite direction; that you
> have to write an explicit and redundant i=i to capture the current
> value when binding.
>> I would hate for Python to lose this simplicity.
>> At least three people, including Guido, have noted than a keyword-only
>> _private parameter solves most of the problems with using default args for
>> constants. Since the _underscore convention is already partly built into the
>> language (import *, help(module), __mangling, __reserved__), we can have
>> other tools like signature introspection also respect the convention.
>> This solution *also* works for the semi-private accumulator parameter of
>> most tail-recursive functions.
> Additional advantages:
> (a) Because it is still a parameter, it *can* be altered for test
> code; it is just obvious that you're doing something unsupported.
> (b) The only patch required is to documentation. Instead of saying
> "Don't do that", the documentation should say "If you just want to
> save state between calls, make it a keyword-only parameter and
> indicate that it is private by prefixing the name with an underscore."
> That is pretty hard to beat from a backwards-compatibility
Um, but you can't save state between calls in a default argument
value, except by the hack of making it a list (or some other mutable
object) and mutating that.
--Guido van Rossum (python.org/~guido)
More information about the Python-ideas