Python:在其中的模块和类之间共享全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3338283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: Sharing global variables between modules and classes therein
提问by emish
I know that it's possible to share a global variable across modules in Python. However, I would like to know the extent to which this is possible and why. For example,
我知道可以在 Python 中跨模块共享全局变量。但是,我想知道这在多大程度上是可能的以及为什么。例如,
global_mod.py
global_mod.py
x = None
mid_access_mod.py
mid_access_mod.py
from global_mod import *
class delta:
def __init__(self):
print x
bot_modif_mod.py
bot_modif_mod.py
import mid_access_mod
import global_mod
class mew:
def __init__(self):
global_mod.x = 5
def main():
m = mew()
d = mid_access_mod.delta()
This prints None, even though all the modules are sharing the global variable x. Why is this the case? It seems like x is evaluated at mid_access_mod.py before it is assigned in bot_modif_mod.py by mew().
这将打印 None,即使所有模块都共享全局变量 x。为什么会这样?似乎 x 在 mid_access_mod.py 中被评估,然后由 mew() 在 bot_modif_mod.py 中分配。
采纳答案by Ned Batchelder
This happens because you are using immutable values (ints and None), and importing variables is like passing things by value, not passing things by reference.
发生这种情况是因为您使用的是不可变值(整数和无),并且导入变量就像按值传递事物,而不是通过引用传递事物。
If you made global_mod.x a list, and manipulated its first element, it would work as you expect.
如果您创建 global_mod.xa 列表,并操作它的第一个元素,它将按您的预期工作。
When you do from global_mod import x, you are creating a name xin your module with the same value as xhas in global_mod. For things like functions and classes, this works as you would expect, because people (generally) don't re-assign to those names later.
当您这样做时from global_mod import x,您将x在您的模块中创建一个名称,其值与xin相同global_mod。对于函数和类之类的东西,这正如您所期望的那样工作,因为人们(通常)以后不会重新分配这些名称。
As Alex points out, if you use import global_mod, and then global_mod.x, you will avoid the problem. The name you define in your module will be global_mod, which always refers to the module you want, and then using attribute access to get at xwill get you the latest value of x.
正如亚历克斯指出的那样,如果您使用import global_mod, 然后global_mod.x,您将避免该问题。您在模块中定义的名称将是global_mod,它始终指的是您想要的模块,然后使用属性访问获取 atx将为您获取 的最新值x。
回答by Alex Martelli
from whatever import *is nota good idiom to use in your code -- it's intended for use, if ever, in an interactive session as a shortcut to save some typing. It basically "snapshots" all names from the module at that point in time -- if you ever rebind any of those names, the snapshot will have grown stale and all sort of problems will ensue. And that's only the beginning of the inextricable mess you're signing up for by using the wretched from ... import *construct.
from whatever import *是不是一个很好的成语在代码中使用-它的目标用户的使用,如果有的话,在交互式会话作为快捷方式来节省一些打字。它基本上是在那个时间点“快照”模块中的所有名称——如果您重新绑定这些名称中的任何一个,快照将变得陈旧,并且会接踵而至。这只是您使用可悲的from ... import *构造注册的不可分割的混乱的开始。
Want my advice? Forget you ever heard about that construct existing and never, ever use it again. Use import global_mod as mand always use thereafter qualifiednames such as m.x-- qualified names are somuch handier and more powerful in Python, than mere barenames, that it ain't even funny. (The as mpart of the importstatement is totally optional and basically exists for conciseness purposes, or sometimes to work around some issues with name clashes; use it when and if you find it handy, since it has no downsides, but don't feel forced or even urged to use if when you don't feel it's necessary).
想要我的建议吗?忘记你曾经听说过那个结构存在,永远不要再使用它。使用import global_mod as m和始终使用后合格的名称,如m.x-限定的名称是这么多的更加便利,并在Python更强大,比单纯的barenames,它甚至不是滑稽。(语句的as m部分import是完全可选的,基本上是为了简洁而存在,或者有时是为了解决名称冲突的一些问题;在您觉得方便时使用它,因为它没有缺点,但不要感到被迫或如果您觉得没有必要,甚至会敦促使用)。
回答by knormoyle
I modified the example to use a list for x, and list assigns (x[0] = ..) as suggested in the top answer, and the print returned the same initial value (None)..This verifies that the "from global_mod import *" is a copy regardless of mutable or not.
我修改了示例以使用 x 的列表,并按照顶部答案中的建议列表分配 (x[0] = ..),并且打印返回相同的初始值(无)。这验证了“来自 global_mod import *" 是一个副本,无论是否可变。
As suggested in the comment "import global_mod" works, if "print global_mod.x = is then used in mid_access_mod.
正如评论“import global_mod”中所建议的那样,如果在mid_access_mod中使用“print global_mod.x =”。
回答by Kevin
As Ned Batchelder mentioned, only the values are shared and not the actual object. If you want to share an object by reference, then you are probably looking Thread-Local Data.
正如 Ned Batchelder 所提到的,只有值是共享的,而不是实际的对象。如果您想通过引用共享一个对象,那么您可能正在寻找Thread-Local Data.
Eg:
例如:
import threading
g = threading.local()
g.population = '7 Billion'
Now, whenever you want to access or change the variable g.population, you will get an updated value of it, provided it is the same thread you are trying to access it from.
现在,无论何时您想要访问或更改变量 g.population,您都会获得它的更新值,前提是它与您试图从中访问它的线程相同。
Read more in the Python documentation:https://docs.python.org/3/library/threading.html#thread-local-data
在 Python 文档中阅读更多内容:https: //docs.python.org/3/library/threading.html#thread-local-data
回答by Chaoz
To solve this problem, just change from global_mod import *to import global_mod.
要解决此问题,只需更改from global_mod import *为import global_mod.
And the new mid_access_mod.pywill be:
新的mid_access_mod.py将是:
import global_mod
class delta:
def __init__(self):
print global_mod.x
The reason for that could be found here.
原因可以在这里找到。
Due to the way references and name binding works in Python, if you want to update some symbol in a module, say foo.bar, from outside that module, and have other importing code "see" that change, you have to import foo a certain way.
由于引用和名称绑定在 Python 中的工作方式,如果您想从该模块外部更新模块中的某个符号,例如 foo.bar,并让其他导入代码“看到”该更改,则必须导入 foo a某种方式。

![Python 请求 requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF 发生违反协议](/res/img/loading.gif)