Python 覆盖全局变量

Python 覆盖全局变量,python,Python,我有两个模块: 常数.py def define_sizes(supersample): global SUPERSAMPLE global WIDTH global HEIGHT global LINE_WIDTH SUPERSAMPLE = supersample WIDTH = 1280*SUPERSAMPLE HEIGHT = 854*SUPERSAMPLE LINE_WIDTH = 1*SUPERSAMPLE

我有两个模块:

常数.py

def define_sizes(supersample):    
    global SUPERSAMPLE
    global WIDTH
    global HEIGHT
    global LINE_WIDTH

    SUPERSAMPLE = supersample
    WIDTH = 1280*SUPERSAMPLE
    HEIGHT = 854*SUPERSAMPLE
    LINE_WIDTH = 1*SUPERSAMPLE

define_sizes(1)
from constants import *


print(WIDTH, HEIGHT, LINE_WIDTH)
# Draw something

define_sizes(4)

print(WIDTH, HEIGHT, LINE_WIDTH)
# Draw the same thing, but bigger
test.py

def define_sizes(supersample):    
    global SUPERSAMPLE
    global WIDTH
    global HEIGHT
    global LINE_WIDTH

    SUPERSAMPLE = supersample
    WIDTH = 1280*SUPERSAMPLE
    HEIGHT = 854*SUPERSAMPLE
    LINE_WIDTH = 1*SUPERSAMPLE

define_sizes(1)
from constants import *


print(WIDTH, HEIGHT, LINE_WIDTH)
# Draw something

define_sizes(4)

print(WIDTH, HEIGHT, LINE_WIDTH)
# Draw the same thing, but bigger
结果是:

1280 854 1
1280 854 1
我希望得到:

1280 854 1
5120 3416 4

为什么呢?我错过了什么?我可以修复它以获得预期的结果吗?

您不能在Python中跨模块共享全局变量。您可以使用配置模块,方法是在项目中需要它的地方导入它,因为只有一个实例,所以您可以将其用作全局配置。它在中有描述。

我推荐类似adarsh对“真实代码”的回答,但如果您需要做的只是尽快破解一些现有代码,您可以尝试使用
test.py
重新导入常量,如:

从常量导入*
打印(宽度、高度、线宽)
定义_大小(4)
从常量导入*
打印(宽度、高度、线宽)

您还必须修改
constants.py
,以便在重新导入时不会将
SUPERSAMPLE
重置为1,例如:

def define_sizes(supersample):
    global SUPERSAMPLE
    global WIDTH
    global HEIGHT
    global LINE_WIDTH

    SUPERSAMPLE = supersample
    WIDTH = 1280*SUPERSAMPLE
    HEIGHT = 854*SUPERSAMPLE
    LINE_WIDTH = 1*SUPERSAMPLE

if not 'SUPERSAMPLE' in globals():
    define_sizes(1)

在这种情况下,我可能会这样做

class Sizes(object):
    def __init__(self, supersample=1)
        self.SUPERSAMPLE = supersample
    def resize(self, supersample)
        self.SUPERSAMPLE = supersample
    @property
    def WIDTH(self): return 1280*self.SUPERSAMPLE
    @property
    def HEIGHT(self): return 854*self.SUPERSAMPLE
    @property
    def LINE_WIDTH(self): return self.SUPERSAMPLE

sizes = Sizes(1)
resize = sizes.resize
然后我可以像这样使用它

from constants import sizes as s

print(s.WIDTH, s.HEIGHT, s.LINE_WIDTH)
# Draw something

s.resize(4)

print(s.WIDTH, s.HEIGHT, s.LINE_WIDTH)
# Draw the same thing, but bigger

一旦从常量导入*名称宽度,
高度
线宽
被导入到该模块的命名空间中,它们引用导入时拥有的值(对象)

即使
常量.WIDTH
被覆盖,变量
test.WIDTH
仍然引用旧值

最干净的解决方案是通过
常量
模块访问这些值:

import constants


print(constants.WIDTH, constants.HEIGHT, constants.LINE_WIDTH)
# Draw something

define_sizes(4)

print(constants.WIDTH, constants.HEIGHT, constants.LINE_WIDTH)
# Draw the same thing, but bigger

一种方法是
返回
值,而不是使用全局值,因此您可以执行
宽度、高度、线宽=定义大小(4)
@Jkdc-当然。在本例中,这是最小的工作示例。在我的真实脚本中,可能有50个常量需要重新定义?将它们全部归还,然后将它们放入全局命名空间将是非常丑陋的……我正在尝试破解现有代码,在一次运行中用不同的<代码>超容量常量执行两次。您可以考虑?@ AdSHS-是的,我已经考虑过了,但是这将需要我重构现有的使用这50个常量的代码。这似乎是唯一合理的方法。无论如何,
Python不支持在多个模块之间共享全局变量:这是一项功能。
解释了它不起作用的原因。但是,我可以使用这个
config
mod
概念,通过只更改一个参数来重新定义所有常量吗?似乎我需要复制
mod
模块中的所有常量代码。您可以使用一个函数,使用参数值作为参数来更改所有需要修改的变量。我不知道你所说的“我需要复制mod模块中的所有常量代码”是什么意思,我必须仔细考虑一下。您是对的。“您还必须修改
常量.py
,以便在重新导入时它不会将仅在
重新加载(常量)
时保持的
超级样本
重置为1。”。如果多次从常量导入*
执行
,则会使用在
sys.modules
中缓存的版本,这样就不会每次重置。