我正在使用机械系统(例如,一个简单的斜齿轮),并希望阻止用户分配在相关枚举中找不到的值。我不熟悉枚举和“pythonic”方法来回答这个问题......所以我的要求是双重的:
以下是代码:
{{1}}
答案 0 :(得分:3)
错误处理应尽可能接近错误的原点。因此,无论用户输入数据还是函数/类都接受数据,应立即检查和处理数据。
你定义Enum的地方完全取决于你,但我倾向于将它们留在顶层,原因如下:
somemod.HAND.LH
或者somemod.HelicalGear.HAND.LH
? 次要更正:您的正如MisterMiyagi评论的那样:使用__init__
应该设置self._hand
。hand
代替_hand
具有以下优点:错误检测hand.setter
中的代码。
在您的setter
代码中,我会执行以下操作:
@hand.setter
def hand(self, hand):
if hand in HAND:
# already an Enum, pass
pass
elif hand in HAND.__members__:
# it's the name of a hand
hand = HAND[hand]
else:
# numeric?
hand = HAND(hand)
# if not, a ValueError will be raised:
# `ValueError: 0 is not a valid Hand`
# save the Enum value
self._hand = hand # or hand.value or hand.name depending on what you want
# returned when HelicalGear.hand is accessed
答案 1 :(得分:1)
一般没有适当的答案 - 这实际上取决于你如何使用你的对象。
python的一个重要概念是duck typing - 也就是说,对象是否合适是由它的特性而不是它的类型定义的。在您的示例中,请考虑枚举是什么:名称到整数的映射。
那么,是否应该强制用户提供枚举条目?或者接受名称,就像你的代码一样?如果以下代码仅对枚举值进行操作,则只需提供该值(例如1
的{{1}})即可。
就个人而言,我更喜欢在实际使用数据[1]的客户端代码中进行隐式类型检查,而不是通过仅存储值的接口代码进行严格的类型检查。后者要求明确写出稍后隐式执行的内容。这意味着您必须使用任何客户端代码更新类型检查。
所以问题不应该是“我在错误输入时引发错误吗?”但“我可以在不使用它的情况下找出错误的输入吗?”如果您使用“是”回答后面的内容,则只需更多实用即可立即引发错误。如果你用“dunno来回答它,那么enum可能适用于我的课程之外”,那么在提出错误时过快会让你失去很大的灵活性。
[1]例外是输入清理。例如,如果您将输入提供给LH
,那么最好是安全而不是抱歉。