Early binding as an option

Chris Torek nospam at torek.net
Thu Aug 4 21:49:44 CEST 2011

>Chris Angelico wrote:
>> def func(x):
>>    len = len  # localize len
>>    for i in x:
>>        len(i)  # use it exactly as you otherwise would

In article <4e39a6b5$0$29973$c3e8da3$5496439d at news.astraweb.com>
Steven D'Aprano  <steve+comp.lang.python at pearwood.info> wrote:
>That can't work. The problem is that because len is assigned to in the body
>of the function, the Python compiler treats it as a local variable. So the
>line len=len is interpreted as <local>len = <local>len, which doesn't yet
>exist. There's no way of saying <local>len = <global>len in the body of the
>So you must either:
>(1) use a different name: length = len
>(2) use a fully-qualified name: import builtins; len = builtins.len

(This is my preferred form, given what one has now, if one is going
to do this in the function body.  Of course in 2.x it is spelled
__builtin__.len instead...)

>(3) do the assignment as a default parameter, which has slightly different
>binding rules: def func(x, <local>len=<global>len)
>(4) manual lookup: len = builtins.__dict__['len']  # untested
>I don't recommend that last one, unless you're deliberately trying to write
>obfuscated code :)

If Python *were* to have some kind of "tie this symbol down now"
operation / keyword / whatever, one could write:

    def func(x):
        snap len # here the new keyword is "snap"
        for i in x:
           ... len(i) ... # use it exactly as you otherwise would

Of course there is no *need* for any new syntax with the other

    def func(x,  len=len) # snapshots "len" at def() time
        for i in x:
           ... len(i) ...

but if one were to add it, it might look like:

    def func(x, snap len):

The advantage (?) of something like a snap or snapshot or whatever
keyword / magic-function / whatever is that you can apply it to
more than just function names, e.g.:

    def func(arg):
        # for this example, assume that arg needs to have the
        # following attributes:
        snap arg.kloniblatt, arg.frinkle, arg.tippy

Here, in the "..." section, a compiler (whether byte-code, or JIT,
or whatever -- JIT makes the most sense in this case) could grab
the attributes, looking up their types and any associated stuff it
wants to, and then assume that for the rest of that function's
execution, those are not allowed to change.  (But other arg.whatever
items are, here.  If you want to bind *everything*, perhaps "snap
arg" or "snap arg.*" -- see below.)

Even a traditional (CPython) byte-code compiler could do something
sort of clever here, by making those attributes "read-only" to
whatever extent the snapshot operation is defined as fixing the
binding (e.g., does it recurse into sub-attributes? does it bind
only the name-and-type, or does it bind name-and-type-and-value,
or name-and-type-and-function-address-if-function, or ... -- all
of which has to be pinned down before any such suggestion is taken
too seriously :-) ).
In-Real-Life: Chris Torek, Wind River Systems
Intel require I note that my opinions are not those of WRS or Intel
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
email: gmail (figure it out)      http://web.torek.net/torek/index.html

More information about the Python-list mailing list