Python 如何以编程方式设置全局(模块)变量?

Python 如何以编程方式设置全局(模块)变量?,python,module,global-variables,Python,Module,Global Variables,我想用一种“程序化”的方式定义globals。类似于我想做的事情是: definitions = {'a': 1, 'b': 2, 'c': 123.4} for definition in definitions.items(): exec("%s = %r" % definition) # a = 1, etc. 具体来说,我想创建一个模块基本常数,其中包含可作为基本常数.electron_mass等访问的变量,其中所有值都是通过解析文件获得的(因此需要以“编程”方式进行赋值)

我想用一种“程序化”的方式定义globals。类似于我想做的事情是:

definitions = {'a': 1, 'b': 2, 'c': 123.4}
for definition in definitions.items():
    exec("%s = %r" % definition)  # a = 1, etc.
具体来说,我想创建一个模块
基本常数
,其中包含可作为
基本常数.electron_mass
等访问的变量,其中所有值都是通过解析文件获得的(因此需要以“编程”方式进行赋值)


现在,上面的
exec
解决方案可以工作了。但是我对此有点不安,因为我担心
exec
不是实现设置模块全局变量目标的最干净的方法。

您可以在globals()返回的字典中设置全局变量:


你说得对,
exec
通常是个坏主意,在这种情况下当然不需要它

内德的回答很好。如果您是模块,另一种可能的方法是导入您自己:

fundamentalconstants.py:

import fundamentalconstants

fundamentalconstants.life_meaning= 42

for line in open('constants.dat'):
    name, _, value= line.partition(':')
    setattr(fundamentalconstants, name, value)

下面是一个更好的方法:

import sys
definitions = {'a': 1, 'b': 2, 'c': 123.4}
module = sys.modules[__name__]
for name, value in definitions.iteritems():
    setattr(module, name, value)

也许您可以描述一下为什么这样更好?@tom10,没有文档可以保证对
globals()
的更改将实际保留对底层模块的更改。它今天工作,明天可能会坏。Nadia的解决方案OTOH是可靠的(因此我有+1;-)。我喜欢这种方式,但关于locals()和globals():当前文档似乎暗示它将始终有效:locals:更新并返回表示当前本地符号表的字典。警告:不应修改本词典的内容;更改可能不会影响解释器使用的局部变量的值。globals:返回表示当前全局符号表的字典。这始终是当前模块的字典。也许这些文件需要调整一下……啊<代码>系统模块[…]是关键…感谢您指出这一点!是时候研究一下
sys
…@Alex的文档了:
globals()
似乎(至少到目前为止)是可更新的。参考:(与ncoghlan讨论)。我更喜欢Nadia的
import[\uuuu name\uuuu]
,而不是硬编码这个模块的名称。有趣的是:我没有想到这一点!诚然,它对更改模块文件名并不健壮,但我还是喜欢使用我的
exec
+1,因为
globals()
确实可以修改()。提出的另一个优点是对
globals()
的更改将保持无错误,但对
locals()
没有这样的保证。这会导致类型错误:'
import sys
definitions = {'a': 1, 'b': 2, 'c': 123.4}
module = sys.modules[__name__]
for name, value in definitions.iteritems():
    setattr(module, name, value)