[Python-ideas] PEP 572: Statement-Local Name Bindings, take three!

Chris Angelico rosuav at gmail.com
Fri Mar 23 07:03:57 EDT 2018


On Fri, Mar 23, 2018 at 9:38 PM, Paul Moore <p.f.moore at gmail.com> wrote:
> On 23 March 2018 at 10:01, Chris Angelico <rosuav at gmail.com> wrote:
>>     # ... except when function bodies are involved...
>>     if (input("> ") as cmd):
>>         def run_cmd():
>>             print("Running command", cmd) # NameError
>>
>>     # ... but function *headers* are executed immediately
>>     if (input("> ") as cmd):
>>         def run_cmd(cmd=cmd): # Capture the value in the default arg
>>             print("Running command", cmd) # Works
>
> What about
>
>     cmd = "Something else"
>     if (input("> ") as cmd):
>         def run_cmd():
>             print("Running command", cmd) # Closes over the "outer"
> cmd, not the statement-local one?
>
> Did I get that right? I don't really like it if so (I think it's
> confusing) but I guess I could live with "well, don't do that then" as
> an answer. And I don't have a better interpretation.

Yes, that would be it. And I agree: Don't do that. It's the same sort
of confusion you'd get here:

def f():
    spam = 1
    class C:
        spam = 2
        def g(x=spam):
            print(spam) # prints 1
            print(x) # prints 2
    C.g()

A class creates a scope that function bodies inside it don't close
over, but their headers are still executed in that scope. So default
argument values "see" those inner variables, but the body of the
function doesn't. It's the same with SLNBs.

> I'm still not convinced I like the proposal, but it's a lot cleaner
> than previous versions, so thanks for that. Far fewer places where I
> said "hmm, I don't understand the implications".

Cool, thanks. That's the idea here.

ChrisA


More information about the Python-ideas mailing list