![](https://secure.gravatar.com/avatar/d67ab5d94c2fed8ab6b727b62dc1b213.jpg?s=120&d=mm&r=g)
On Tue, Dec 7, 2021 at 6:16 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-12-05 08:14, Chris Angelico wrote:
Closures cannot be executed without a context. Consider:
def f(x=lambda: (a:=[])): if isinstance(x, FunctionType): x = x() print(a)
Here's the problem: The name 'a' should be in the context of f, but that context*does not exist* until f starts executing.
Frankly, I would consider this another disadvantage of late-bound arguments as defined under your proposal. I do not want argument defaults to be able to have the side effect of creating additional local variables in the function. (There is also the question of whether they could assign in this manner to names already used by other arguments, so that one argument's default could potentially override the default of another.)
Unless it's otherwise denied, all valid forms of expression should be valid in an argument default. They are already valid in early-bound defaults:
def f(): ... def g(a=(b:=42)): ... ... return locals() ... f() {'b': 42, 'g': <function f.<locals>.g at 0x7f9a7083ef00>}
Since early-bound defaults are evaluated at definition time, the assignment happens in the outer function. If anything, it's more logical for it to be a part of the inner function, but for early-bound defaults, that's not possible. Though I wouldn't recommend that people actually *do* this sort of thing. Legal doesn't mean recommended. But if someone does, it needs to behave logically and correctly. ChrisA