Objects in Python

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Aug 26 19:29:06 EDT 2012


On Sun, 26 Aug 2012 16:12:40 -0400, Dennis Lee Bieber wrote:

> On 26 Aug 2012 13:43:33 GMT, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> declaimed the following in
> gmane.comp.python.general:
> 
> 
> 
>> (In some older versions of Python, wildcard imports are allowed, and
>> the function then falls back on a namespace instead of fixed locations.
>> That is no longer the case in Python 3.2 at least.)
>>
> 	Must be really old:

Not really. You get a SyntaxWarning back to at least 2.2, but the 
fallback namespace behaviour does work through to 2.7:

py> assert 'pi' not in globals()
py> def test():
...     from math import *
...     print pi
... 
<stdin>:1: SyntaxWarning: import * only allowed at module level
py> test()
3.14159265359

What I didn't realise until just now is that it's a bit more complicated 
than that. Using import * in a function you can end up with two distinct 
sets of locals, those using numbered memory slots (effectively address-
based), and those using a dict namespace.

If you assign to a name in the function, it still gets turned into a 
memory slot rather than being in a dict. Decompiling the function shows 
that such local are still accessed using LOAD_FAST and STORE_FAST op-
codes. (That's the case all the way back to Python 1.5 at least.)

But if you *don't* assign to the name, Python uses LOAD_NAME instead, 
which searches namespace. In this case pi is not found in the global or 
built-in namespaces, so there must be a local, dict-based namespace in 
addition to the usual LOAD_FAST slots. Hence, two distinct sets of locals.


-- 
Steven



More information about the Python-list mailing list