我应该如何最好地模拟和/或避免 Python 中的枚举? [复制]
Posted
技术标签:
【中文标题】我应该如何最好地模拟和/或避免 Python 中的枚举? [复制]【英文标题】:How should I best emulate and/or avoid enum's in Python? [duplicate] 【发布时间】:2010-09-11 15:11:15 【问题描述】:在一些 Python 项目中,我一直在使用一个小类来模拟 Enums。有没有更好的方法,或者这对某些情况最有意义?
类代码在这里:
class Enum(object):
'''Simple Enum Class
Example Usage:
>>> codes = Enum('FOO BAR BAZ') # codes.BAZ will be 2 and so on ...'''
def __init__(self, names):
for number, name in enumerate(names.split()):
setattr(self, name, number)
【问题讨论】:
同意。抱歉,我应该早点找到的。 【参考方案1】:以前曾有人提议将枚举包含在该语言中,但被拒绝了(请参阅http://www.python.org/dev/peps/pep-0354/),尽管您可以使用现有的包而不是编写自己的实现:
枚举:http://pypi.python.org/pypi/enum SymbolType(与枚举不太一样,但仍然有用):http://pypi.python.org/pypi/SymbolType Or just do a search【讨论】:
【参考方案2】:最常见的枚举案例是作为状态或策略设计模式一部分的枚举值。枚举是要使用的特定状态或特定的可选策略。在这种情况下,它们几乎总是某些类定义的一部分
class DoTheNeedful( object ):
ONE_CHOICE = 1
ANOTHER_CHOICE = 2
YET_ANOTHER = 99
def __init__( self, aSelection ):
assert aSelection in ( self.ONE_CHOICE, self.ANOTHER_CHOICE, self.YET_ANOTHER )
self.selection= aSelection
然后,在这个类的客户端中。
dtn = DoTheNeeful( DoTheNeeful.ONE_CHOICE )
【讨论】:
【参考方案3】:here 有很多很好的讨论。
【讨论】:
【参考方案4】:在***模块上下文中,我更经常看到的是:
FOO_BAR = 'FOO_BAR'
FOO_BAZ = 'FOO_BAZ'
FOO_QUX = 'FOO_QUX'
...后来...
if something is FOO_BAR: pass # do something here
elif something is FOO_BAZ: pass # do something else
elif something is FOO_QUX: pass # do something else
else: raise Exception('Invalid value for something')
请注意,在这里使用is
而不是==
是有风险的——它假定人们使用的是your_module.FOO_BAR
而不是字符串'FOO_BAR'
(这通常被拘留,以使is
匹配,但这当然不能指望),因此根据上下文可能不合适。
这样做的一个好处是,通过查看存储对该字符串的引用的任何地方,它的来源立即显而易见; FOO_BAZ
比 2
更清晰。
除此之外,您建议的课程冒犯了我对 Python 的敏感性的另一件事是使用 split()
。为什么不直接传入元组、列表或其他可枚举的对象?
【讨论】:
【参考方案5】:枚举的内置方法是:
(FOO, BAR, BAZ) = range(3)
这适用于小型集合,但有一些缺点:
您需要手动计算元素的数量 你不能跳过值 如果添加一个名称,还需要更新范围号有关python中完整的枚举实现,请参见: http://code.activestate.com/recipes/67107/
【讨论】:
值得注意的是,如果范围大小与元素计数不匹配,Python 将引发异常。【参考方案6】:我从看起来很像 S.Lott 的答案的东西开始,但我只重载了“str”和“eq”(而不是整个对象类),所以我可以打印和比较枚举的值。
class enumSeason():
Spring = 0
Summer = 1
Fall = 2
Winter = 3
def __init__(self, Type):
self.value = Type
def __str__(self):
if self.value == enumSeason.Spring:
return 'Spring'
if self.value == enumSeason.Summer:
return 'Summer'
if self.value == enumSeason.Fall:
return 'Fall'
if self.value == enumSeason.Winter:
return 'Winter'
def __eq__(self,y):
return self.value==y.value
Print(x) 将产生名称而不是值,并且持有 Spring 的两个值将彼此相等。
>>> x = enumSeason(enumSeason.Spring)
>>> print(x)
Spring
>>> y = enumSeason(enumSeason.Spring)
>>> x == y
True
【讨论】:
以上是关于我应该如何最好地模拟和/或避免 Python 中的枚举? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
同时安装多个 Python 发行版会遇到啥问题,以及如何最好地避免这些问题? [复制]
如何使用 Node.js 为所有连接最好地实现 HTTPS?
如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?
如何最好地处理 Neuraxle 管道中的错误和/或丢失数据?