Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何方便地定义命名整数常量列表?_Python_Dictionary_Global Variables_Config_Constants - Fatal编程技术网

Python 如何方便地定义命名整数常量列表?

Python 如何方便地定义命名整数常量列表?,python,dictionary,global-variables,config,constants,Python,Dictionary,Global Variables,Config,Constants,我想定义常量,例如A=10;B=20,具有以下特性: “正常”访问:例如A.value+B.value==30(甚至A+B==30) 允许重复值:例如A=10;B=10 每个变量的关联字符串:例如A.name==“A” 清单:例如,[v.name代表常数中的v] IDE支持:自动完成名称、重新分解等 添加新常量需要一次更改 可导入:例如,从配置导入常量 归根结底,6号房产才是问题所在。差不多 A = 10 B = 20 A_NAME = "A" B_NAME = "B" CONSTANTS

我想定义常量,例如
A=10;B=20,具有以下特性:

  • “正常”访问:例如
    A.value+B.value==30
    (甚至
    A+B==30
  • 允许重复值:例如
    A=10;B=10
  • 每个变量的关联字符串:例如
    A.name==“A”
  • 清单:例如,
    [v.name代表常数中的v]
  • IDE支持:自动完成名称、重新分解等
  • 添加新常量需要一次更改
  • 可导入:例如,
    从配置导入常量
  • 归根结底,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)时失败。还可以定义
    Enum
    的子类,构造函数采用
    value
    。但是再一次,
    A=10;B=10
    将映射到同一实例,即使名称不同。现在还可以向构造函数添加名称(或任何其他未使用但与众不同的参数)来解决此问题。但我认为这种做法是不干净的。例如,
    A=(“A”,10);B=(“B”,10);def\uuuu init\uuuuu(self,\uuu,value):…

    通过使用
    globals()
    将dict内容复制到全局变量中,可以使常量dict内容不那么冗长:

    CONSTANTS = {"A": 10, "B": 20}
    globals().update(CONSTANTS)
    
    print(B)  # prints 20
    

    通过使用
    globals()
    将dict内容复制到全局变量中,您可以减少常量dict内容的冗长程度:

    CONSTANTS = {"A": 10, "B": 20}
    globals().update(CONSTANTS)
    
    print(B)  # prints 20
    

    你有没有考虑过使用这个系列

    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)
    

    你有没有考虑过使用这个系列

    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)
    
    @property
    def value(self):
        return self._value_[1]
    
    用成员的名称填充
    \u value\u
    属性,会导致无法找到具有相同值的其他成员。唯一的缺点是,生成的成员的
    属性都引用其内部
    \u值
    属性。事实上,
    被定义为。因此,无需进一步修改,我们将面临:
    Const1.A.value==('A',42)

    如果需要,可以使用属性覆盖此行为

    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)
    
    @property
    def value(self):
        return self._value_[1]
    
    免责声明:不鼓励访问隐藏属性,因此不应将其视为“干净”解决方案

    可以调整标准枚举模块以提供所需的行为

    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)
    
    @property
    def value(self):
        return self._value_[1]
    
    用成员的名称填充
    \u value\u
    属性,会导致无法找到具有相同值的其他成员。唯一的缺点是,生成的成员的
    属性都引用其内部
    \u值
    属性。事实上,
    被定义为。因此,无需进一步修改,我们将面临:
    Const1.A.value==('A',42)

    如果需要,可以使用属性覆盖此行为

    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)
    
    @property
    def value(self):
        return self._value_[1]
    

    为什么您的提案需要继承自
    enum
    ?为什么不能用属性定义类,并根据需要重写
    \uuuuu add\uuuuu
    等?但是我如何访问此类的元素名称呢?对于
    类C():A=1;B=2
    ,如何访问
    C.B.name
    或类似的东西?Bleh,疯狂的int子类。它们看起来都很好,也很方便,直到它们传播到一个意想不到的地方,你的程序开始打印
    疯狂的internaleum。奇怪的名称
    而不是
    3
    ,或者duck键入检查采用了错误的代码路径,因为它不希望整数具有
    名称
    属性。我完全同意。通过属性访问该值对我来说是完全正确的,当然更安全。@user2357112以消除可能的误解。“疯狂的int子类”是一个很好的东西,但不是必需的。对我来说,“value”属性就足够了。为什么您的提案需要继承自
    enum
    ?为什么不能用属性定义类,并根据需要重写
    \uuuuu add\uuuuu
    等?但是我如何访问此类的元素名称呢?对于
    类C():A=1;B=2
    ,如何访问
    C.B.name
    或类似的内容