在 Python 3.6 中访问静态字典
accessing a static dict in Python 3.6
我有一个罗盘方向的枚举 class,如下所示。
我还有一个 'opposites' dict 在同一个 class 中声明。
from enum import Enum
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
opposites = {N: S, S: N, E: W, W: E}
# static method to provide the opposite values.
@staticmethod
def other(com):
return opposites[com]
当我试图打电话给其他人时,例如。 Compass.other(Compass.N),我希望得到 Compass.S,但我却得到了..
TypeError: 'Com' object is not subscriptable
这是怎么回事,我该如何用 Python 方式解决这个问题?
@RomanPerekhrest 纯粹是因为响应速度而获得荣誉,但我需要更多的争论才能得到我想要的东西,这是 class 中的枚举。如果向 Enum 中输入了错误的输入,则对 Enum 本身的转换会引发错误..
对我有用的 class 文件 folloeinh RomanPerekhrest 看起来像这样。
from enum import Enum
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
_opposites = {N: S, S: N, E: W, W: E}
@staticmethod
def other(item):
return Compass(Compass._opposites.value[item.value])
if __name__ == "__main__":
print(Compass.other(Compass.E))
不过,@EthanFurman 的回复很漂亮,我确实实现了,但我还没有完全理解...
您的自定义 class Compass
派生自 Enum
class 这是 枚举 但不是可订阅序列。
考虑这一行:
print(type(Compass.N))
虽然你期望它输出 <class 'str'>
- 它输出:
<enum 'Compass'>
访问枚举对象属性使用value
属性。
print(Compass.N.value) # prints "N"
print(Compass.opposites.value) # prints {'S': 'N', 'N': 'S', 'E': 'W', 'W': 'E'}
正确的 Compass.other()
函数声明应如下所示:
# static method to provide the opposite values.
@staticmethod
def other(item):
if item in Compass.opposites.value:
return Compass.opposites.value[item]
else:
raise AttributeError('unknown compass direction :', item)
用法:
print(Compass.other(Compass.N.value)) # prints "S"
基本问题是 opposite
正在转变为 Enum
成员,就像 N
、S,
E 和 W
一样。下一个问题是 opposite
中的值——它们 而不是 被转换为 Enum
成员。
理想情况下,我们会有这样的东西:
# NB: does not currently work!
class Compass(Enum):
N = 'N', S
S = 'S', N
E = 'E', W
W = 'W', E
Compass.E.opposite is Compass.W # True
这目前不起作用的原因有两个:
- 从普通值到
Enum
成员的最终转换发生在 class 创建之后
- 不允许转发引用
因此,为了获得干净的(呃)实现和 API 我们必须 post- 处理 Enum
。我会使用装饰器:
class reverse():
"decorator to add reverse lookups to Enum members"
def __init__(self, reverse_map):
"initialize decorator by saving map"
self.reverse_map = reverse_map
def __call__(self, enum):
"apply map to newly created Enum"
for first, second in self.reverse_map.items():
enum[first].opposite = enum[second]
enum[second].opposite = enum[first]
# don't forget to return the now-decorated Enum
return enum
并在使用中:
@reverse({'N':'S', 'E':'W'})
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
>>> Compass.N.opposite is Compass.S
True
我有一个罗盘方向的枚举 class,如下所示。 我还有一个 'opposites' dict 在同一个 class 中声明。
from enum import Enum
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
opposites = {N: S, S: N, E: W, W: E}
# static method to provide the opposite values.
@staticmethod
def other(com):
return opposites[com]
当我试图打电话给其他人时,例如。 Compass.other(Compass.N),我希望得到 Compass.S,但我却得到了..
TypeError: 'Com' object is not subscriptable
这是怎么回事,我该如何用 Python 方式解决这个问题?
@RomanPerekhrest 纯粹是因为响应速度而获得荣誉,但我需要更多的争论才能得到我想要的东西,这是 class 中的枚举。如果向 Enum 中输入了错误的输入,则对 Enum 本身的转换会引发错误..
对我有用的 class 文件 folloeinh RomanPerekhrest 看起来像这样。
from enum import Enum
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
_opposites = {N: S, S: N, E: W, W: E}
@staticmethod
def other(item):
return Compass(Compass._opposites.value[item.value])
if __name__ == "__main__":
print(Compass.other(Compass.E))
不过,@EthanFurman 的回复很漂亮,我确实实现了,但我还没有完全理解...
您的自定义 class Compass
派生自 Enum
class 这是 枚举 但不是可订阅序列。
考虑这一行:
print(type(Compass.N))
虽然你期望它输出 <class 'str'>
- 它输出:
<enum 'Compass'>
访问枚举对象属性使用value
属性。
print(Compass.N.value) # prints "N"
print(Compass.opposites.value) # prints {'S': 'N', 'N': 'S', 'E': 'W', 'W': 'E'}
正确的 Compass.other()
函数声明应如下所示:
# static method to provide the opposite values.
@staticmethod
def other(item):
if item in Compass.opposites.value:
return Compass.opposites.value[item]
else:
raise AttributeError('unknown compass direction :', item)
用法:
print(Compass.other(Compass.N.value)) # prints "S"
基本问题是 opposite
正在转变为 Enum
成员,就像 N
、S,
E 和 W
一样。下一个问题是 opposite
中的值——它们 而不是 被转换为 Enum
成员。
理想情况下,我们会有这样的东西:
# NB: does not currently work!
class Compass(Enum):
N = 'N', S
S = 'S', N
E = 'E', W
W = 'W', E
Compass.E.opposite is Compass.W # True
这目前不起作用的原因有两个:
- 从普通值到
Enum
成员的最终转换发生在 class 创建之后 - 不允许转发引用
因此,为了获得干净的(呃)实现和 API 我们必须 post- 处理 Enum
。我会使用装饰器:
class reverse():
"decorator to add reverse lookups to Enum members"
def __init__(self, reverse_map):
"initialize decorator by saving map"
self.reverse_map = reverse_map
def __call__(self, enum):
"apply map to newly created Enum"
for first, second in self.reverse_map.items():
enum[first].opposite = enum[second]
enum[second].opposite = enum[first]
# don't forget to return the now-decorated Enum
return enum
并在使用中:
@reverse({'N':'S', 'E':'W'})
class Compass(Enum):
N = 'N' # North
S = 'S' # South
E = 'E' # East
W = 'W' # West
>>> Compass.N.opposite is Compass.S
True