如何通过区分类型来隔离枚举?

问题描述 投票:3回答:2

以下代码定义了两个枚举

class Insect:
    BEE = 0x00
    WASP = 0x01
    BUMBLEBEE = 0x02


class Breakfast:
    HAM = 0x00
    EGGS = 0x01
    PANCAKES = 0x02


b = Insect.WASP
if b == Breakfast.EGGS:
    print("ok")

正如条件所说明的那样,人们可以对一个完全不同的枚举进行测试。如何通过类型而不是通过不同的值来隔离枚举,以便上面的测试会产生错误?

更新

我发现这是从Python 2迁移到Python 3的道路上的一个更好的点。

感谢wim的建议,如果我尝试比较苹果和橙子,下面的代码会产生错误。

from enum import Enum


class Apple(Enum):
    RED_DELICIOUS = 0x00
    GALA = 0x01
    FUJI = 0x02

    def __eq__(self, other):
        if type(other) is not type(self):
            raise Exception("You can't compare apples and oranges.")
        return super().__eq__(other)


class Orange(Enum):
    NAVEL = 0x00
    BLOOD = 0x01
    VALENCIA = 0x02

    def __eq__(self, other):
        if type(other) is not type(self):
            raise Exception("You can't compare apples and oranges.")
        return super().__eq__(other)


apple = Apple.GALA
if apple == Orange.BLOOD:
    print("ok")
python enums type-safety
2个回答
7
投票

不要使用自定义类。使用stdlib的enum类型,他们会在这里做正确的事情。

from enum import Enum

class Insect(Enum):
    ...

如果你想要一个严重的崩溃:

class MyEnum(Enum):

    def __eq__(self, other):
        if type(other) is not type(self):
            raise Exception("Don't do that")
        return super().__eq__(other)

但是我谨慎对待这种设计,因为:

  1. 枚举实例通常通过身份而非平等进行比较
  2. 在Python中,很少(没有?)先例可以进行相等比较,从而引发错误

3
投票

关于等式测试的一些注释,为什么它不应该引发异常,以及正确的类型测试。

为什么==不应该提出异常?

平等测试在Python中不断使用,特别是在容器中:listdictset,仅举几例,依靠相等测试来查找成员,返回成员,更改成员,删除成员等。如果你的Apple Enum每次都会提高它与非Apple进行比较,它会破坏它所添加的任何容器。

自定义类型失败等式测试(以及其他比较测试)的正确方法

def __eq__(self, other):
    if not isinstance(other, self.__class__):
        return NotImplented   # note:  NOT RAISE
    ... comparison here ...

NB。以上测试已内置于Enum类型。

适当的型式试验

如果你真的,真的想确保你没有得到你不想要的类型,结果应该是一个错误:

var1 = ...
if not isinstance(var1, SomeTypeHere):
    raise SomeException

但上面的代码不应该是任何丰富的比较方法*。


*丰富的比较方法是__eq____ne____ge____gt____le____lt__

© www.soinside.com 2019 - 2024. All rights reserved.