使用Enums检查python中的类/实例的属性

时间:2016-06-28 21:01:11

标签: python enums

我正在使用机械系统(例如,一个简单的斜齿轮),并希望阻止用户分配在相关枚举中找不到的值。我不熟悉枚举和“pythonic”方法来回答这个问题......所以我的要求是双重的:

  1. 在python中更容易让输入错误发生并使用后续代码来管理影响?
  2. 应该在使用它的类中定义枚举吗?我并不打算将此枚举用于其他地方......我觉得很奇怪,只是让它在我文件的开头挂出。
  3. 以下是代码:

    {{1}}

2 个答案:

答案 0 :(得分:3)

  1. 错误处理应尽可能接近错误的原点。因此,无论用户输入数据还是函数/类都接受数据,应立即检查和处理数据。

  2. 你定义Enum的地方完全取决于你,但我倾向于将它们留在顶层,原因如下:

    • 需要使用它们的其他代码:
      somemod.HAND.LH或者somemod.HelicalGear.HAND.LH
    • 如果您以后创建另一个具有右手和左手项目的课程怎么办?
  3. 次要更正:您的__init__应该设置self._hand正如MisterMiyagi评论的那样:使用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,那么最好是安全而不是抱歉。