基于 Enum 迭代或索引列表
Iterate or index list based on Enum
我有一个包含 4 个元素的小型枚举列表 (class Type(Enum): One,Two,Three,Four
),我想知道是否有办法将枚举与全局列表相关联 (List = [Type(0),Type(1),Type(2),Type(3)
]。
我知道我可以使用语法 List[ Type.Two.value ]
访问此列表。但我希望有一个简单的方法来丢失 .value
。这不是打字问题——我不介意输入长的描述性变量名。但是列表和枚举直接是 related/associated,所以如果列表将枚举尊重为迭代器,那将是更可取的。有没有简单的方法可以解决这个问题?
我在 Blender 的环境中工作,构建一个附加组件,如果这有什么不同的话。我对 python 也很陌生 - 大约一周了,所以如果你有明显的要点,请不要遗漏。
我对C/C++很熟悉,以防有雷同之处。我非常喜欢创建数据库列表并以一种方式关联迭代器类型,以防止使用与其关联的索引类型名称以外的任何内容访问列表(所以你不会犯像 Cars[my_boat_index]
这样的错误)
感谢任何建议!
您似乎希望通过将索引类型限制为特定类型(例如枚举)来限制对列表的访问。
虽然我不认为这是个好主意,但你绝对可以做到:
from enum import Enum
class MyEnum(Enum):
ZERO = 0
ONE = 1
TWO = 2
class MyList(list):
def __getitem__(self, item):
assert isinstance(item, MyEnum)
return super().__getitem__(item.value)
ml = MyList([1, 2, 3])
print(ml[MyEnum.ONE])
print(ml[1]) # error here
为什么要将对列表的访问限制为与列表索引的默认类型(即 int
)不同的类型?
如果您希望拥有特定的属性,为什么不定义一个 class,或者如果您想要通过特定值进行索引,为什么不使用字典?
也许你应该提供一些关于你实际希望做什么的信息 - Python 不是 C/C++,它可能有一些完全有效的方法来做你想做的事情,而不必模仿 C/C++ 的作用。
如果您不想限制,而只是想迭代(这似乎与问题所述不同):
for my_value in MyEnum:
print(ml[my_value])
如果您不想限制对仅具有该类型的索引的访问,那么您可以省略 assert
语句。
来自文档 https://docs.python.org/3/library/enum.html Enumerations support iteration, in definition order
这样您就可以遍历它们来构建列表,例如:
from enum import Enum
class Numbers(Enum):
ONE = 1
TWO = 2
THREE = 3
assert [Number.value for Number in Numbers] == [1,2,3]
将 Enum
转换为列表非常简单:
list(Type)
# [<Type.ONE: 1>, <Type.TWO: 2>, <Type.THREE: 3>, <Type.FOUR: 4>]
使用 Type
个成员作为索引来访问列表有点复杂:
- 默认情况下,成员值从 1 开始
- 但容器索引从 0 开始
- 并且成员没有
__index__
和 __int__
方法
easy/simple 解决方案有两个:
- 使用
IntEnum
代替Enum
- 从
0
开始计数
所以:
class Type(IntEnum):
ZERO = 0
ONE = 1
TWO = 2
THREE = 3
IntEnum
成员可以在 int
所在的任何地方使用,因此它们可以很好地用作索引值。
比较复杂的方案是用一个正则Enum
,把你需要的方法加进去,返回值的时候减1:
class Type(Enum):
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
def __index__(self):
return self.value - 1
def __int__(self):
return self.value - 1
即使您开始添加 __index__
和 __int__
方法,您仍然应该从零开始计数,而不是做减一技巧,因为这会在您以后导致更多问题习惯 Python 的工作方式。
我有一个包含 4 个元素的小型枚举列表 (class Type(Enum): One,Two,Three,Four
),我想知道是否有办法将枚举与全局列表相关联 (List = [Type(0),Type(1),Type(2),Type(3)
]。
我知道我可以使用语法 List[ Type.Two.value ]
访问此列表。但我希望有一个简单的方法来丢失 .value
。这不是打字问题——我不介意输入长的描述性变量名。但是列表和枚举直接是 related/associated,所以如果列表将枚举尊重为迭代器,那将是更可取的。有没有简单的方法可以解决这个问题?
我在 Blender 的环境中工作,构建一个附加组件,如果这有什么不同的话。我对 python 也很陌生 - 大约一周了,所以如果你有明显的要点,请不要遗漏。
我对C/C++很熟悉,以防有雷同之处。我非常喜欢创建数据库列表并以一种方式关联迭代器类型,以防止使用与其关联的索引类型名称以外的任何内容访问列表(所以你不会犯像 Cars[my_boat_index]
这样的错误)
感谢任何建议!
您似乎希望通过将索引类型限制为特定类型(例如枚举)来限制对列表的访问。
虽然我不认为这是个好主意,但你绝对可以做到:
from enum import Enum
class MyEnum(Enum):
ZERO = 0
ONE = 1
TWO = 2
class MyList(list):
def __getitem__(self, item):
assert isinstance(item, MyEnum)
return super().__getitem__(item.value)
ml = MyList([1, 2, 3])
print(ml[MyEnum.ONE])
print(ml[1]) # error here
为什么要将对列表的访问限制为与列表索引的默认类型(即 int
)不同的类型?
如果您希望拥有特定的属性,为什么不定义一个 class,或者如果您想要通过特定值进行索引,为什么不使用字典?
也许你应该提供一些关于你实际希望做什么的信息 - Python 不是 C/C++,它可能有一些完全有效的方法来做你想做的事情,而不必模仿 C/C++ 的作用。
如果您不想限制,而只是想迭代(这似乎与问题所述不同):
for my_value in MyEnum:
print(ml[my_value])
如果您不想限制对仅具有该类型的索引的访问,那么您可以省略 assert
语句。
来自文档 https://docs.python.org/3/library/enum.html Enumerations support iteration, in definition order
这样您就可以遍历它们来构建列表,例如:
from enum import Enum
class Numbers(Enum):
ONE = 1
TWO = 2
THREE = 3
assert [Number.value for Number in Numbers] == [1,2,3]
将 Enum
转换为列表非常简单:
list(Type)
# [<Type.ONE: 1>, <Type.TWO: 2>, <Type.THREE: 3>, <Type.FOUR: 4>]
使用 Type
个成员作为索引来访问列表有点复杂:
- 默认情况下,成员值从 1 开始
- 但容器索引从 0 开始
- 并且成员没有
__index__
和__int__
方法
easy/simple 解决方案有两个:
- 使用
IntEnum
代替Enum
- 从
0
开始计数
所以:
class Type(IntEnum):
ZERO = 0
ONE = 1
TWO = 2
THREE = 3
IntEnum
成员可以在 int
所在的任何地方使用,因此它们可以很好地用作索引值。
比较复杂的方案是用一个正则Enum
,把你需要的方法加进去,返回值的时候减1:
class Type(Enum):
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
def __index__(self):
return self.value - 1
def __int__(self):
return self.value - 1
即使您开始添加 __index__
和 __int__
方法,您仍然应该从零开始计数,而不是做减一技巧,因为这会在您以后导致更多问题习惯 Python 的工作方式。