python - 在枚举构造函数中使用 super() 时出现 NameError

标签 python python-2.7 enums super nameerror

我正在使用 Python 2.7.10 和 enum34 库。我正在尝试执行以下操作:

from enum import Enum


class Foo(Enum):
    def __init__(self):
        pass


class Bar(Foo):
    VALUE = 1

    def __init__(self, value):
        super(Bar, self).__init__()

运行此代码时,我收到错误 NameError: global name 'Bar' is not defined。有人可以帮助解释为什么我收到此错误以及是否可以调用枚举子类的父构造函数?提前致谢!

编辑:Olivier Melançon 的追溯(已编辑路径名称):

Traceback (most recent call last):
  File "/.../test.py", line 9, in <module>
    class Bar(Foo):
  File "/.../lib/python2.7/site-packages/enum/__init__.py", line 236, in __new__
    enum_member.__init__(*args)
  File "/.../test.py", line 13, in __init__
    super(Bar, self).__init__()
NameError: global name 'Bar' is not defined

Process finished with exit code 1

最佳答案

问题是 Bar.VALUE.__init__Bar 存在之前被调用。

您可以在 EnumMeta.__new__ 中看到发生这种情况的位置,但即使不看代码,它也几乎必须以这种方式工作:Enum 类的全部要点在于它的枚举成员是常量值,充当类的属性,同时也是类的实例。

因此,此代码将在 3.4+ 中产生与 stdlib enum 模块完全相同的错误,以及与多个第三方 enum 替换的类似错误。

一般来说,如果您有 Enum 层次结构,您应该只将值放在“叶”类中,而只将行为放在非叶类中。但是,Restricted subclassing of enumerations 中实际明确记录的唯一限制。在非叶类中没有值,因此从技术上讲,您尝试做的事情应该是合法的,即使它不寻常并且从未明确打算工作。


如果您使用的是 Python 3,则有一个非常简单的解决方法:只需使用 super() 而不是 super(Bar, self),这并不重要Bar 还不存在。

在 Python 2 中,由于这不可行,您需要手动模拟 super。对于完全的一般性,这意味着编写代码来遍历 mro 等等,但是由于包括两个或更多 Enum 类的多重继承无论如何都不会起作用,你只需静态硬编码就可以了:

def __init__(self, value):
    Foo.__init__(self)

或者,如果您更改设计以将所有行为放在非叶类中,那也可以:

class Foo(Enum):
    def __init__(self):
        pass

class Bar(Foo):
    def __init__(self, value):
        super(Bar, self).__init__()

class Baz(Bar):
    VALUE = 1

最有可能的是,无论您实际尝试完成什么,都可以以更好的方式完成,而无需进行任何这些更改。但是由于您的玩具示例没有完成任何事情,因此没有更多内容可以展示。

关于python - 在枚举构造函数中使用 super() 时出现 NameError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51033366/

相关文章:

python - 多处理通过共享内存传递字典数组

c++ - 实现同时具有枚举和类行为的东西

python - 在 Google 云存储桶中使用 PIL 更改图像大小(从 GCloud 中的虚拟机)

python - 在 PyTorch 和 Numpy 中快速生成形状为 (1, 1, 256) 和 (10, 1, 256) 的多个 3D 张量

python - 在python中使用mysql获取最后两个查询

将文件放到 iSeries 上时 Python ftplib 错误 426

具有多个数据类型字段的 Java 枚举?

c - 枚举错误,变量未声明

python - Debug=True 时 Django 1.11 404 页面

python - 将 python 代码打印为 PDF