Mup*_*pet 13 python coding-style numpy
我注意到现在很多库似乎更喜欢使用字符串而不是enum-type变量来获取参数.
人们之前会使用枚举,例如dateutil.rrule.FR为星期五,似乎这已经转向使用字符串(例如'FRI').
numpy(或pandas)也是如此,其中searchsorted例如使用字符串(例如side ='left'或side ='right')而不是定义的枚举.为了避免疑问,在python 3.4之前,这可以很容易地实现为枚举:
class SIDE:
RIGHT = 0
LEFT = 1
Run Code Online (Sandbox Code Playgroud)
enums-type变量的优点很明显:你不能在不引发错误的情况下拼错它们,它们为IDE提供了适当的支持等.
那么为什么要使用字符串,而不是坚持使用枚举类型呢?这不会使程序更容易出现用户错误吗?它不像枚举产生开销 - 如果有的话,它们应该稍微更高效.那么这种范式转变的时间和原因何时发生?
ddd*_*bbb 10
我知道这个问题已经得到了解答,但有一件事根本没有得到解决:事实上,当使用 Enum 存储的值时,必须显式调用 Python Enum 对象来获取它们的值。
>>> class Test(Enum):
... WORD='word'
... ANOTHER='another'
...
>>> str(Test.WORD.value)
'word'
>>> str(Test.WORD)
'Test.WORD'
Run Code Online (Sandbox Code Playgroud)
解决这个问题的一个简单方法是提供一个实现__str__()
>>> class Test(Enum):
... WORD='word'
... ANOTHER='another'
... def __str__(self):
... return self.value
...
>>> Test.WORD
<Test.WORD: 'word'>
>>> str(Test.WORD)
'word'
Run Code Online (Sandbox Code Playgroud)
是的,添加.value
并不是什么大不了的事,但仍然带来不便。使用常规字符串不需要额外的工作,不需要额外的类,也不需要重新定义任何默认的类方法。尽管如此,在许多情况下,必须显式转换为字符串值,而简单的转换str
不会有问题。
[更新]
截至今天(2019 年),Python 引入了数据类——结合可选的类型注释和静态类型分析器(如 mypy),我认为这是一个已解决的问题。
至于效率,与大多数计算机语言相比,Python 中的属性查找有些昂贵,因此我猜出于性能原因,某些库可能仍会选择避免使用它。
【原答案】
恕我直言,这是一个品味问题。有些人喜欢这种风格:
def searchsorted(a, v, side='left', sorter=None):
...
assert side in ('left', 'right'), "Invalid side '{}'".format(side)
...
numpy.searchsorted(a, v, side='right')
Run Code Online (Sandbox Code Playgroud)
是的,如果你searchsorted
和你一起打电话,side='foo'
你可能会AssertionError
在运行时得到一个方法 - 但至少这个错误很容易在回溯中被发现。
虽然其他人可能更喜欢(对于您强调的优点):
numpy.searchsorted(a, v, side=numpy.CONSTANTS.SIDE.RIGHT)
Run Code Online (Sandbox Code Playgroud)
我赞成第一个,因为我认为很少使用的常量不值得命名空间的浪费。你可能不同意,人们可能会因为其他问题而与任何一方保持一致。
如果您真的在乎,没有什么可以阻止您定义自己的“枚举”:
class SIDE(object):
RIGHT = 'right'
LEFT = 'left'
numpy.searchsorted(a, v, side=SIDE.RIGHT)
Run Code Online (Sandbox Code Playgroud)
我认为这不值得,但这又是一个品味问题。
[更新]
斯蒂芬提出了一个公平的观点:
一旦需要更改此类枚举的值,在许多地方查找和替换字符串就不是我的乐趣:-)
我可以看到在没有命名参数的语言中这是多么痛苦 - 使用示例,您必须搜索字符串'right'
并获得大量误报。在 Python 中,您可以缩小搜索范围side='right'
。
当然,如果您正在处理一个已经定义了一组枚举/常量(如外部 C 库)的接口,那么是的,一定要模仿现有的约定。
小智 6
我认为枚举更安全,特别是对于有多个开发人员的大型系统.
一旦需要改变这种枚举的价值,在许多地方查找和替换字符串不是我的乐趣:-)
最重要的标准是恕我直言:用于模块甚至包中一个字符串似乎没问题,在公共API中我更喜欢枚举.