Question about math.pi is mutable

Chris Angelico rosuav at gmail.com
Mon Nov 9 07:36:54 EST 2015


On Mon, Nov 9, 2015 at 11:22 PM, BartC <bc at freeuk.com> wrote:
> I tried this code:
>
> a=10
> print (a)
>
> del a
> #print (a)
>
> a=20
> print (a)
>
> That sort of confirms what you are saying: that names don't even come into
> existence until the first time they are encountered. They don't just contain
> None, or some other value which means the name itself exists, but it hasn't
> been initialised to anything. And that del removes the name completely from
> the set that are known.
>
> That makes Python unlike any other language I've used.

It's a direct consequence of the dynamic namespacing. You'll find
similar results in JavaScript/ECMAScript if you play around with
prototype-based inheritance, which has a similar rule ("if the
property isn't here, look at the prototype") to the Python namespacing
rule ("if the name isn't in this namespace, look at the next one
outward").

And you're absolutely correct. Unused names do not "contain None" in
any sense - they utterly do not exist. When you 'del' a name, that
name utterly ceases to exist.

> On the other hand, if I put the above code into a function and then call the
> function, attempting to print a just after it's been deleted results in:
>
>  UnboundLocalError: local variable 'a' referenced before assignment

That's a special case of NameError that was added to make it a bit
easier to track down certain types of bug.

> So while local names can presumably be manipulated just like globals, that
> doesn't stop being implemented via a fixed slot in a table.
>

Global names are simply module attributes, so they can be manipulated
in many ways. Function locals are not; there's no way to say
"current_stack_frame.foo = 2", so there's no need to hack around with
name lookups. (The locals() dictionary isn't meant to be modified, and
changes may or may not have effect on actual local name bindings.)

ChrisA



More information about the Python-list mailing list