如何在Python中表示枚举
我知道,我知道,在和中已经有类似的问题。但他们的问题和答案并不是我想要的。此外,它们是一个被锁定的问题,所以我不能为它们添加新的答案。SMH 首先,让我们澄清问题,了解其范围。在其他静态语言中使用enum时,如下所示:如何在Python中表示枚举,python,enums,Python,Enums,我知道,我知道,在和中已经有类似的问题。但他们的问题和答案并不是我想要的。此外,它们是一个被锁定的问题,所以我不能为它们添加新的答案。SMH 首先,让我们澄清问题,了解其范围。在其他静态语言中使用enum时,如下所示: public enum Size { SMALL=0, MIDIUM=1, LARGE=2, BIG=2 // There can possibly be an alias } 我们希望它能帮助我们: 在引用值时要防止输入错误。例如,var f
public enum Size
{
SMALL=0,
MIDIUM=1,
LARGE=2,
BIG=2 // There can possibly be an alias
}
我们希望它能帮助我们:
var foo=Size.SMALL
是有效的,var bar=Size.SMAL
应该会生成一个糟糕的错误HTTP404=“未找到”、HTTP200=“确定”、…
。(因此,基于范围(N)
的实现是不可接受的。)publicvoidfoo(大小){…}
def parser(value\u来自\u线路):…
希望使用一些本机值(例如整数或字符串等),而不是使用Enum成员。这是Python 3中标准枚举的棘手部分:
assert 2==MY_ENUM。只有当MY_ENUM从
派生时,MY_值才会起作用(并且没有默认的IntEnum
,尽管自己对一个进行子类化并不困难)strengum
不起作用,即使MY_ENUM是从在MY_ENUM中断言2
派生的IntEnum
TL;DR:使用 因此,我的Python解决方案以满足问题中的3个标准为基础,其实现似乎比新的更简单 使用现在很简单
# definition syntax
SIZE = enum("Size", SMALL=0, MEDIUM=1, LARGE=2, BIG=2)
# usage on referencing
print(SIZE.SMALL) # got 0, instead of <SIZE.SMALL: 0>
try:
print(SIZE.SMAL) # got AttributeError
assert False, "should not arrive this line"
except AttributeError:
pass
# usage on comparison and contains-check
assert SIZE.MEDIUM == 1 # works. It won't work when using standard Enum (unless using IntEnum)
assert 1 in SIZE # works. It won't work when using standard Enum (unless you wrote it as SIZE(1)).
# usage on regulating input value
def t_shirt_size(size):
if size not in SIZE:
raise ValueError("Invalid input value")
print("Placing order with size: %s" % size)
t_shirt_size(SIZE.MEDIUM) # works
t_shirt_size(2) # also want this to work
try:
t_shirt_size(7) # got AssertionError
assert False, "This line should not be reached!"
except ValueError:
pass
定义语法
大小=枚举(“大小”,小=0,中=1,大=2,大=2)
#引用的用法
打印(大小。小)#得到0,而不是
尝试:
打印(SIZE.SMAL)#属性错误
断言False,“不应到达此行”
除属性错误外:
通过
#比较和包含检查的用法
assert SIZE.MEDIUM==1#有效。使用标准枚举时,它将不起作用(除非使用IntEnum)
断言1在大小上有效。当使用标准枚举时,它将不起作用(除非您将其写成大小(1))。
#调节输入值的用法
def t恤衫尺寸(尺码):
如果大小不一致:
提升值错误(“无效输入值”)
打印(“下订单大小:%s”%size)
t恤衫尺码(中号)#合适
t恤衫(2号)#也希望它能起作用
尝试:
t恤衫尺码(7号)#有断言错误
断言False,“不应到达此行!”
除值错误外:
通过
编辑1:我实际上意识到,在功能方面,有一个主要是我下面的一行程序实现的超集。但是,有一种情况是,标准枚举不能满足我的需要。我希望这些值在我的枚举中是一等公民;我希望我的t\u shirt\u size(…)
函数接受实际值,而不仅仅是枚举成员。标准枚举方法不允许以下两种用法:assert SIZE.MEDIUM==1
或assert 1 in SIZE
编辑2:考虑到人们倾向于将这个主题定型为重复的主题,我计划将我的方法实际实现为一个独立的模块,包含大量的文档。我甚至给它起了一个很酷的名字,
venum
,V代表价值。就是在那个时候,我在pypi中检查了这个名称,发现已经有一个同名的包,使用与我相同的方法,并且。就这样解决了。我只想改为::-) 使用Python 3的Enum
实现:
from enum import IntEnum
class SIZE(Enum):
SMALL = 0
MEDIUM = 1
LARGE = 2
BIG = 2
@classmethod
def contains(cls, value):
return any([e.value == value for e in cls])
并使用:
print(SIZE.SMALL) # got <SIZE.SMALL: 0>
print(SIZE.SMAL) # got AttributeError
def t_shirt_size(size):
assert size in SIZE, "Invalid input value"
place_order_with_size(size)
t_shirt_size(SIZE.MEDIUM) # works
t_shirt_size(7) # got AssertionError
打印(大小.小)#得到
打印(SIZE.SMAL)#属性错误
def t恤衫尺寸(尺码):
在大小中断言大小,“输入值无效”
使用尺寸(尺寸)下订单
t恤衫尺码(中号)#合适
t恤衫尺码(7号)#有断言错误
我不明白您的问题与您链接的问题有何不同。为什么那里的答案不能回答你的问题?@Aran Fey这些问题都没有阐明要求,因此,他们的答案往往基于不同回答者心中的不同假设。嗯?有什么需要澄清的?我认为,“如何表示枚举”这个问题相当清楚。你的枚举能做什么,而现有答案中的其他枚举却做不到?好吧,当我发布这个问答时,至少我做了我的家庭作业。你在发表评论之前做过自己的评论吗?大多数简单的解决方案类MY_ENUM:NAME1=“value1”
不满足我的要求#3,即允许在MY_ENUM中输入if值:…
检查。其他一些人有一个假设“如果你需要数值,这里是最快的方法:dog,cat,rabbit=range(3)
”,这不是我想要的。你是认真的吗?你列出的所有问题都与这个问题无关。只有当您选择了一种不好的方式来表示枚举时,这些问题才会存在。所有这些都是答案的问题,而不是问题。如果你看到一个糟糕的答案,就投反对票。你的问题和另一个问题没有什么不同。谢谢你的否决票。实际上,我知道在Python3中有一个标准的Enum
模块,从功能上讲,它主要是我的单行程序实现的超集。然而,有一种情况是它不适合我的需要。我希望这些值在我的枚举中是一等公民;我希望我的t\u shirt\u size(…)
函数接受实际值,而不仅仅是枚举成员。标准枚举方法不允许以下两种用法:assert SIZE.MEDIUM==1
或assert 1 in SIZE
。现在,你的具体回答不符合我的需要。但我不会投反对票。你也公平吗?@raylou:assert SIZE.MEDIUM==1
与IntEnum一起工作
print(SIZE.SMALL) # got <SIZE.SMALL: 0>
print(SIZE.SMAL) # got AttributeError
def t_shirt_size(size):
assert size in SIZE, "Invalid input value"
place_order_with_size(size)
t_shirt_size(SIZE.MEDIUM) # works
t_shirt_size(7) # got AssertionError