如何抑制子类python枚举上的“索引应为字符串”类型错误

2024-10-01 22:43:39 发布

您现在位置:Python中文网/ 问答频道 /正文

以下通过切片访问pythonEnum成员的示例来自其documentation(其中Period恰好是一个Enum):

list(Period)[:2]

当对Enum进行子类化时,我认为允许使用跳过list中包装的语法是有意义的(即,使使用我的子类的语法与访问listtuple成员的语法更一致):

import enum

class MyEnumMeta(enum.EnumMeta):
  def __getitem__(self, indexOrSlice):
    if isinstance(indexOrSlice, (int, slice)):
      return list(self)[indexOrSlice]
    else:
      return enum.EnumMeta.__getitem__(self, indexOrSlice)

class MyEnum(enum.Enum, metaclass=MyEnumMeta): pass

class Period(MyEnum):
  A = "a"
  B = "b"
  C = "c"

print(Period["A"])
print(Period[1])    # type: ignore[misc]
print(Period[:2])   # type: ignore[misc]

尽管这似乎执行得很好,mypy会引发以下错误,除非我将# type: ignore[misc]附加到试图使用“更精简”语法的每一行(这使得语法实际上更精简):

Enum index should be a string

(您可以在mypy code中搜索,以查看相关部分)

我不喜欢添加一个语句,它将抑制发生在同一行中的任何合法[misc]错误。此外,mypy努力提出这个错误(而且Enum不允许直接使用压缩语法)这一事实让我想知道,是否有一些很好的理由说明,即使以Enum文档中演示的方式,也不可能通过整数或切片访问Enum成员

如果我不应该做我想做的事,有人能解释一下原因吗?否则,有人能建议一个更好的方法来处理mypy吗?如果mypy犯了一个错误,没有预料到它遇到的Enum实际上可能是Enum的子类,正如我所建议的那样覆盖__getitem__,我如何报告该错误


Tags: selftype错误语法成员enumlistclass
2条回答

如果我有一个枚举Foo,如下所示:

from enum import Enum

class Foo(Enum):
    BAR = 1
    BAZ = 2

然后,关于enum的许多奇妙之处之一是,已经有多种方法可以访问enum的成员。以下示例位于交互式控制台中:

>>> Foo(1)
<Foo.BAR: 1>
>>> Foo['BAR']
<Foo.BAR: 1>
>>> Foo.BAR
<Foo.BAR: 1>
>>> Foo(Foo.BAR)
<Foo.BAR: 1>

因此,您以自己的方式重写EnumMeta.__getitem__可能是不明智的,因为这可能不是其他阅读您的代码的人所期望的。enum的内置特性是,您可以通过将成员的名称(字符串)传递到方括号中来访问成员。否则将违反代码用户的期望,并且正如MyPy错误所示,它还将违反类型检查器的期望。将enum显式转换为类外的list有些不同-类型检查器和代码的任何人类读者都清楚list可以使用整数或切片进行索引

您的更改没有问题。然而,Mypy的枚举支持是硬编码的,所以它无法识别它们

相关问题 更多 >

    热门问题