【问题标题】:Python: change global variable from within another filePython:从另一个文件中更改全局变量
【发布时间】:2018-05-19 13:06:32
【问题描述】:

在我的主类中,我使用在另一个名为 config.py 的文件中定义的全局变量 ADDRESS。 我想通过调用 config.py 中的函数来从我的主类中更改 ADDRESS 的值。

在我的主要课程中,我有:

from config import ADDRESS, change_address
change_address("192.168.10.100")
print("new address " + ADDRESS)

在我的配置文件中,我有以下内容:

ADDRESS = "0.0.0.0"

def change_address(address):
    global ADDRESS
    ADDRESS = address
    print("changed address to: " + ADDRESS)

我的配置文件中的打印语句正确打印了新地址 192.168.10.100。 但是,我的主类中的打印语句打印 0.0.0.0。 我在这里错过了什么?

【问题讨论】:

  • 您的import 将一个新的局部变量ADDRESS 绑定到配置中ADDRESS 变量所引用的字符串。当您调用change_address() 时,config 中的ADDRESS 变量现在指的是不同的字符串。您自己的局部变量仍然引用原始字符串。

标签: python


【解决方案1】:

from config import ADDRESS, change_address 所做的只是从 config 模块的命名空间中获取 ADDRESSchange_address 并将其转储到当前模块的命名空间中。现在,如果您在config 的命名空间中重新分配ADDRESS 的值,则当前模块将看不到它——这就是命名空间的工作方式。这就像做以下事情:

>>> some_namespace = {'a':1}
>>> globals().update(some_namespace)
>>> a
1
>>> some_namespace
{'a': 1}
>>> some_namespace['a'] = 99
>>> a
1
>>> some_namespace
{'a': 99}

最简单的解决方案?不要破坏命名空间:

import config
config.change_address("192.168.10.100")
print("new address " + config.ADDRESS)

【讨论】:

【解决方案2】:

我建议您尽量不要更改模块中的全局状态。相反,我会重新编写代码,使 config.py 中的ADDRESS 不会改变。如果您的应用程序的配置可以从调用更改为调用,我会将配置更改为:

ADDRESS = '0.0.0.0'

def get_default_config():
    return {'address': ADDRESS, 'some_other_config_value': 'foo'}

然后我会做:

app_config = config.get_default_config()
app_config = "192.168.10.100"
print("new address " + app_config['address']

作为一般规则,在其他模块中更改变量/常量的值并不是一个好主意。

注意:您也可以创建一个配置类,以便您可以访问配置值,例如 config.address。

我建议您阅读 stackexchange 帖子Why is Global State so Evil?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    相关资源
    最近更新 更多