动态创建可以从任何地方导入的不可变常量?

Dynamically creating immutable constants that can be imported from everywhere?

在我的 python 包中,我有一个 entry_point run.py 文件,它将种子(例如 42)和 cuda 设备(例如“cuda:0”)作为命令行参数。

由于这两个变量在整个包的不同位置都使用,我不想将它们作为参数从一个函数传递到另一个函数。因此,我做了以下事情:

utils.py:

import random

import numpy as np
import torch


def set_device(device: str):
    global _DEVICE
    _DEVICE = torch.device(device)


def get_device() -> torch.device:
    return _DEVICE


def set_seed_number(seed: int):
    global _SEED
    _SEED = seed


def set_seeds():
    torch.manual_seed(_SEED)
    random.seed(_SEED)
    np.random.seed(_SEED)

然后在 run.py 内,我通过调用设置这些变量一次:

from package.utils import set_device, set_seed_number

...

set_device(device)
set_seed_number(seed=seed)

现在我可以从包中的任何位置导入和调用 get_device()set_seeds 方法,而不必将这些变量作为参数传递。

到目前为止,这种方法工作正常,但在读到强烈建议不要在 python 中使用全局变量后,我想知道是否有更 pythonic 的方法来实现上述目标?

我已经考虑过有一个专用的单例 class,它会动态地实例化这些常量,但我不确定它是否以及如何工作以及是否会被认为更多“python ic”毕竟。

已经感谢您的回答,也许您可​​以指出一些似乎适用于这种情况的模式。我只能猜测我不是第一个尝试实现上述目标的人。

老实说,如果很少使用 global 并且只有在有充分理由的情况下才使用它,我看不出它有什么问题。 (我认为强烈反对aganstglobal是因为它经常被滥用。)

但是关于您建议的自定义 class,没有必要实例化它——您只需设置 class 个变量即可。

main.py

import settings

settings.set_foo(3)
print(settings.Settings.foo)

settings.py

class Settings:
    pass

def set_foo(x):
    Settings.foo = x

这在原则上与将您的数据项放入其他可变集合中没有什么不同,例如一个字典,然后将它们设置在定义它的模块(或导入它的另一个模块)的函数中。

main.py

import settings

settings.set_foo(3)
print(settings.settings['foo'])

settings.py

settings = {}

def set_foo(x):
    settings['foo'] = x