[我正在寻找一种访问__init__.py文件中定义的全局变量(profit_benchmark)的Python方法,并且在其中一个模块(routines.py)中修改了它的值,现在我想访问具有修改后的值的profit_benchmark在另一个模块中(network.py)
这是我的文件夹结构:
__ init __。py
profit_benchmark = 50
routines.py
from so import profit_benchmark
profit_benchmark = 60
network.py
from so import profit_benchmark
print(profit_benchmark)
输出:
50
我期望输出为60,因为在variable.py中修改了变量Profit_benchmark
我的问题:如何在network.py中访问profit_benchmark变量的新值,以使输出为60
[第一件事:Python没有真正的全局变量,只有模块级全局变量-每个模块都是一个不同的名称空间,而全局变量只是其定义的模块的'全局'。
[第二件事:import
语句与C或PHP include
完全不同-它不会在导入模块中“复制”整个导入的模块,而是加载导入的模块(如果尚未加载)已经)并使其在导入名称空间中可用
实际上是这个:
import so
是]的快捷方式>
from importlib import importmodule so = importmodule("so")
和此:
from so import profit_benchmark
是]的快捷方式>
from importlib import importmodule so = importmodule("so") profit_benchmark = so.profit_benchmark del so
如juanpa(简要地解释),在第二种情况下,您最终得到两个都指向同一对象的名称(
so.profit_benchmark
和your_importing_module.profit_benchmark
)。现在Python变量不是C样式的内存位置,它们是名称空间中的name =>对象条目(通常是字典中的key:value对)。分配实际上只是使分配的命名点指向另一个对象,因此当您执行此操作时>
from so import profit_benchmark profit_benchmark = 42
第一条语句在当前名称空间中创建名称“ profit_benchmark” 并将其绑定到与
到so.profit_benchmark
指向的对象相同的对象,第二条语句重新绑定当前名称空间的profit_benchmark
名称42
int对象,so.profit_benchmark
完全不变。所有这些(还有更多非常有用的知识)在this Ned Batchelder's article中有更深入的解释。另一方面,当您这样做时>
import so so.profit_benchmark = 42
您要重新绑定的名称实际上是
so
的“全局”profit_benchmark
-实际上已成为so
模块对象的属性(在运行时,模块也是对象),因此任何其他读取[ C0]现在将获取更新的值。有人说:您要求使用“ pythonic方式”,而pythonic方式实际上是尽可能避免可变的全局状态(这就是python的“ globals”不是真正的原因之一。全球)。事实是,一旦养成了尽可能多地使用纯函数和类的习惯,而当您需要在函数状态之间具有some共享状态时,您就会意识到无需编写单个代码就可以编写大型程序“可写”全局变量(nb:只读全局变量当然完全可以,当您开始变异或什至更糟糕的是重新绑定全局变量时,问题就开始了。)
所以问题是:为什么您认为您根本不需要一个可写的全局变量?有许多种方法可以避免它们,但是“正确”的解决方案取决于具体的用例,您对此一无所知。