我想定义常数,例如A = 10; B = 20
,具有这些属性:
- "正常"访问:例如
A.value + B.value == 30
(甚至A + B == 30
( - 允许重复值:例如
A = 10; B = 10
- 每个变量的关联字符串:例如
A.name == "A"
- 清单:例如
[v.name for v in CONSTANTS]
- IDE支持:自动完整名称,重新输入等等
- 添加新常数需要一个更改
- 可进口:例如
from config import CONSTANTS
最后,属性#6是问题所在。像
A = 10
B = 20
A_NAME = "A"
B_NAME = "B"
CONSTANTS = { A_NAME: A, B_NAME: B }
基本上是解决方案。但是我想避免使用此详细代码(如果可能的话(。
此尝试非常接近:
import enum
class CONSTANTS(enum.IntEnum):
A = 10
B = 20
assert CONSTANTS.A + CONSTANTS.B == 30
assert CONSTANTS.A.name == "A"
assert CONSTANTS.__members__.keys() == ["A", "B"]
assert CONSTANTS.__members__.values() == [10, 20]
,但是当两个常数具有相同的值(属性#2(时失败。一个人还可以用 value
的构造函数来定义Enum
的子类。但是同样,即使名称有所不同,A = 10; B = 10
也会映射到同一实例。现在,人们还可以在构造函数中添加名称(或任何其他未使用但独特的参数(,以使此问题消失。但是我认为这种方法不洁。例如,A = ("A", 10); B = ("B", 10); def __init__(self, _, value): ...
。
您可以通过使用 globals()
将dict内容复制到全局变量的情况下使常数少详细。
CONSTANTS = {"A": 10, "B": 20}
globals().update(CONSTANTS)
print(B) # prints 20
您是否考虑过使用名为Tuple Collection?
from collections import namedtuple
IntConst = namedtuple('IntConst', ['name', 'value'])
A = IntConst('A',10)
B = IntConst('B',20)
他们按字段符合您的"正常访问" ..
A.value + B.value
当多个IntConst
具有相同的值时,他们不会抱怨...
A = IntConst('A',10)
B = IntConst('B',10)
他们将提供关联的字符串...
A.name
他们将允许列表...
CONSTANTS = list()
CONSTANTS.extend([A,B])
[v.name for v in CONSTANTS]
您的IDE可能已经支持namedtuple
。添加更多常数只需您创建IntConst
namedtuple
的实例即可。至于导入,您只需在命名空间中创建一个IntConst
值的列表,它们将成为import
语句的有效目标。
他们唯一不给您要求的东西是能够从中输入整数值。相反,您将获得一个包含两个IntConst
实例的元组。
>>> A+B
('A', 10, 'B', 10)
免责声明:访问隐藏属性是不建议的,因此不应被视为'干净'解决方案!
标准枚举模块可以进行调整提供所需的行为。
import enum
class Const1(enum.Enum):
A = 42
B = 42
def __init__(self, size):
self._value_ = (self.name, size)
self.size = size
class Const2(enum.IntEnum):
A = 42
B = 42
def __init__(self, size):
enum.IntEnum.__init__(self)
self._value_ = (self.name, size)
用成员名称填充_value_
属性,呈现出别名查找机制无法找到具有相同值的其他成员。唯一的缺点是,生产成员的value
属性均参考其内部_value_
属性。实际上,value
定义为DynamicClassAttribute
。因此,没有进一步的修改我们面对:Const1.A.value == ('A', 42)
。
如果需要,可以使用属性来覆盖此行为。
@property
def value(self):
return self._value_[1]