Easy questions from a python beginner

Alf P. Steinbach /Usenet alf.p.steinbach+usenet at gmail.com
Mon Jul 12 20:18:06 EDT 2010


* Steven D'Aprano, on 13.07.2010 01:34:
> On Mon, 12 Jul 2010 20:28:49 +0200, Alf P. Steinbach /Usenet wrote:
>
>> As I see it it doesn't matter whether the implementation is CPython call
>> frame slots or that mechanism called something else or a different
>> mechanism called the same or a different mechanism called something
>> different; what IMO matters is same semantics, that any assignment to a
>> variable within a routine serves as a compile time declaration, creating
>> that local variable in advance, unless, with Python 3.x., that name has
>> been declared as a 'global' or 'nonlocal'.
>>
>> So, this is a possible point of disagreement.
>>
>> I say the semantics of local variable creation are part of the language
>> definition, but I get the /impression/ that maybe you think it's
>> CPython-specific, that e.g.
>>
>>     def foo():
>>         x
>>         x = 0
>>
>> might not raise an unassigned variable exception with some conforming
>> Python implementation, i.e. different effect for same code with
>> different implementations, that this is at least /unspecified behavior/
>> in Python?
>
> Almost.
>
> I believe that "any assignment to a variable within a routine serves as a
> compile time declaration" is a promise of the language, but what an
> implementation does in response to that declaration is unspecified. So
> long as foo() raises NameError, or a subclass of it, it will be a
> conforming Python implementation.
>
> That's what Python 1.5 does, and I think if some competing implementation
> targeted 1.5 we'd still be happy to call it Python. (Although we might
> wonder about the author's sanity...) Implementations are free to subclass
> NameError, as CPython does with UnboundLocalError, but mustn't raise a
> completely unrelated error, or no error at all. E.g. I don't think it
> would be acceptable to implicitly create new names and bind them to some
> arbitrary default value.
>
> E.g. an implementation might do something like this:
>
> * when parsing the function, prior to compiling the byte-code, tag
>    every name with a sigil representing whether it is local or non-local;
> * compile a single byte-code for name lookup;
> * when executing that instruction, if the name is tagged as a local,
>    search only the local namespace, otherwise search the nonlocal,
>    global and builtin namespaces;
> * when displaying names to the user (say, in tracebacks) suppress
>    the sigil.
>
> Under this implementation, no variable actually exists until it is
> assigned to.
>
> This is equivalent to shifting the decision to use LOAD_FAST or
> LOAD_GLOBAL to runtime rather than compile time, so it would probably
> hurt performance rather than increase it, but it would still be a
> conforming implementation.
>
> But of course I'm not Guido, and he has the final word on what counts as
> acceptable behaviour.

The 3.1.1 docs explicitly require UnboundLocalError (I just checked).

So, at least for 3.x it is not an implementation detail.

Anyway, your phrase "actually exist" presumably refers to storage allocation. 
That is an implementation detail. As a similar implementation scheme, a compiler 
can in certain cases detect that a variable is only assigned once, and 
substitute the value whereever that variable is used, not allocating any storage 
for it. This is the case in Python, in C++ and in almost any language. We don't 
start doubting the existence of variables in general (as some in the Python 
community do) on such grounds. More to the point of this sub-thread, it would be 
impossible to reason about things if one had to take into account the particular 
implementation's details at all times. Doing that renders most terms, including 
"exist", pretty meaningless and useless, since you would have to check whether 
each particular variable was optimized away or not: for the purpose of 
discussing existence in Python, what matters is portable effect.

Summing up, how CPython implements the required semantics, is irrelevant.

:-)


Cheers from Norway,

- Alf

-- 
blog at <url: http://alfps.wordpress.com>



More information about the Python-list mailing list