Question

I had to read and fix some really bad scripts today, and I'm baffled because I don't understand why they worked at all. To be clear, I would never do something like this. My question refers to how namespaces work in this case, not why it is a bad idea or how to do this better.

Anyway, the situation in its simplest form can be reproduced with two files.

test.py:

import math
math.myvar = "Is this a local variable?"
math.pi = 1.2345
import u

u.py:

import math
print(math.myvar)
print(math.pi)

Now, to my surprise running python test.py will print myvar and the wrong value for pi. Of course, without the import math in u.py it will not print myvar. How does this happen? I though imported modules were entirely local in scope.

Était-ce utile?

La solution

Modules are global singletons. They are stored in the sys.modules mapping, to prevent having to load every module each time it is used somewhere.

All globals in a module are exposed as attributes on the module object; math.pi is one such global. You can alter these globals by assigning to them, and because modules are singleton objects, every reference to the module object will see the change.

Remember, Python names are references; the name math is indeed 'local' to your module, but it is still a reference to the global <module 'math' from '/usr/lib/python2.7/lib-dynload/math.so'> object.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top