我想创建一个名为“constants.py”的模块,其中包含特定于我的系统的所有常量。
为了提供灵活性,我希望能够像这样直接访问常量:
constants.power_1
constants.power_2
constants.data_rate_1
constants.data_rate_2
...
因为它很短,或者通过这样的字典访问常量:
constants['system_1']['power']
constants['system_2']['power']
constants['system_1']['data_rate']
constants['system_2']['data_rate']
...
因为有时我在循环中使用常量时它很有用,如下所示:
systems = ['system_1', 'system_2']
for system in systems:
power = constants[system]['power']
var_2 = var_1 * power
我的问题是我不能同时使用这两种方法。
我能做什么:
选项 1. 忘记访问像
constants.power_1
这样的常量,而只拥有像 constants['power_1']
这样的字典。所以我在'constants.py'中这样声明它们:
constants['power_1'] = 10
constants['system_1']['power'] = constants['power_1']
并像这样使用它们:
from constants import *
var_2 = var_1 * constants['power_1']
var_2 = var_1 * constants['system_1']['power']
缺点:
import *
,即使我只导入一本字典,我更喜欢简单的导入。['']
)。选项 2.为我的字典使用中间名称。所以我在'constants.py'中这样声明它们:
power_1 = 10
varname['system 1']['power'] = power_1
并像这样使用它们:
import constants
var_2 = var_1 * constants.power_1
var_2 = var_1 * constants.varname['system 1']['power']
缺点:
varname
找到一个有意义的名字,因为它没有必要(我可以放system
,但这是多余的)。你有其他方法来解决这个问题吗?
说实话,如果你想这样做,我建议创建一个基于类的结构,它将为分层常量提供类似字典的结构,并为单个常量提供平面命名空间。
Constants.py 可能看起来像这样
class Constants:
def __init__(self):
# flat - you can also maybe load this from a JSON so you don't touch this often
self._flat_constants = {
"power_1": 10,
"power_2": 20,
"data_rate_1": 100,
"data_rate_2": 200,
}
# heirachy
self._nested_constants = {
"system_1": {
"power": self._flat_constants["power_1"],
"data_rate": self._flat_constants["data_rate_1"],
},
"system_2": {
"power": self._flat_constants["power_2"],
"data_rate": self._flat_constants["data_rate_2"],
},
}
def __getitem__(self, key):
# First look through the flat ones
if key in self._flat_constants:
return self._flat_constants[key]
# Then check nested ones
if key in self._nested_constants:
return self._nested_constants[key]
raise KeyError(f"Constant '{key}' not found.")
def __getattr__(self, name):
# Allow direct access to flat constants
if name in self._flat_constants:
return self._flat_constants[name]
raise AttributeError(f"'Constants' object has no attribute '{name}'")
然后您可以通过在您计划的任何地方初始化来使用它,知道您可以使用点来访问平面常量(power_1 ...),并使用
['system_1]['power']
来访问嵌套常量。
提示:如果您最终决定从 JSON 加载,则应该添加一些逻辑,以便在键中发现重复项时引发异常(JSON 中允许重复项)。
希望这对您有所帮助,如果您有疑问,请告诉我。