python - Cython 中的枚举成员名称重复 - 重新声明错误?
问题描述
Cython 似乎不允许我重用枚举成员名称。
我有以下枚举,我正在尝试 cythonize:
from enum import Enum
class Fruit(Enum):
UNKNOWN = 0
APPLE = 1
ORANGE = 2
class Animal(Enum):
UNKNOWN = 0
DOG = 1
CAT = 2
但以下导致'UNKNOWN' redeclared
编译错误:
cpdef enum Fruit:
UNKNOWN = 0
APPLE = 1
ORANGE = 2
cpdef enum Animal:
UNKNOWN = 0
DOG = 1
CAT =
我该如何解决上述问题?
另外,理想情况下,我希望将其NULL
用作枚举成员名称,而不是UNKNOWN
. 但这似乎NULL
是 Cython 的特权关键字,尽管它不适用于 CPython。有什么解决方法吗?
解决方案
在 C 中,以下代码无法编译:
enum Foo{
A
};
enum Bar{
A
};
因为在 C 中,枚举不会引入新的名称范围,因此如果您A
对两种类型Foo
和Bar
.
Cython 会翻译(如果它只是应用其通常的方案并且不会因编译器错误而停止):
#foo.pyx
cpdef enum Fruit:
UNKNOWN = 0
cpdef enum Animal:
UNKNOWN = 0
类似于
enum __pyx_t_3foo_Fruit {
__pyx_e_3foo_UNKNOWN = 0
};
enum __pyx_t_3foo_Animal {
__pyx_e_3foo_UNKNOWN = 0
};
正如我们所见,这不是有效的 C,因此 Cython 的选择是生成错误。“问题”是 Cython 没有将类型名称 ( Fruit
, Animal
) 包含到生成的枚举值名称中,因此在 Cython 中您可以将它们区分为Fruit.UNKNOWN
和Animal.UNKNOWN
,它们将映射到相同的 C 标识符.
至少有两种选择:
A: C 中通常的策略是使用前缀来区分枚举,例如:
cpdef enum Fruit:
FRUIT_UNKNOWN = 0
cpdef enum Animal:
ANIMAL_UNKNOWN = 1
或 B:您可以让 Cython 通过将它们放在不同的 pxd 文件中来完成这项工作,这些文件被导入到生成的 pyx 文件中:
# Fruit.pxd
cpdef enum Fruit:
UNKNOWN = 0
#Animal.pxd
cpdef enum Animal:
UNKNOWN = 0
# foo.pyx:
cimport Fruit
cimport Animal
# use Fruit.UNKNOWN and Animal.UNKNOWN
在生成的代码中,枚举名称将具有模块名称(即Fruit
和Animal
),因此从 C 编译器的角度来看是不一样的。
推荐阅读
- python - 只有最后一行 Pandas 网络抓取数据出现在电子表格中
- docker - Docker 安装程序:gpg 在 Windows 上找不到有效的 OpenPGP 数据
- android - 为什么 ADB 突然停止同时检测超过 15 个设备?
- url - 标记 URL 重复内容
- r - R中的循环分组
- c# - 如何将 Spritefont 文件编译成 XNB 文件?
- database - 当两个页面相邻时,会发生多少次随机IO?
- javascript - Next.js 包罗万象/作为路由
- c# - 控制 C# windows 窗体的大小问题,在编译时看起来不同,在运行时看起来不同
- javascript - 如何渲染反应组件出现错误“TypeError:x.IndexPage 不是函数”