简体   繁体   English

通过更改和导入模块在Python中传递“局部”变量?

[英]Passing “local” variables in Python by changing and importing modules?

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 : test.py

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

u.py : 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. 现在,令我惊讶的是,运行python test.py将输出myvar和pi的错误值。 Of course, without the import math in u.py it will not print myvar . 当然,如果没有在u.py import math ,它将不会输出myvar How does this happen? 这是怎么发生的? I though imported modules were entirely local in scope. 尽管导入的模块在作用域上完全是本地的。

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. 它们存储在sys.modules映射中,以防止每次在某个地方使用每个模块时都必须加载它。

All globals in a module are exposed as attributes on the module object; 模块中的所有全局变量都作为属性公开在模块对象上。 math.pi is one such global. math.pi就是这样的一个整体。 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 ; 记住,Python名称是引用 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. 名称math实际上确实是模块的“本地”名称,但是它仍然是对<module 'math' from '/usr/lib/python2.7/lib-dynload/math.so'>对象中的全局<module 'math' from '/usr/lib/python2.7/lib-dynload/math.so'>的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM