[Python-ideas] Tweaking closures and lexical scoping to include the function being defined

Jim Jewett jimjjewett at gmail.com
Thu Sep 29 02:41:41 CEST 2011

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


More information about the Python-ideas mailing list