枚举功能集¶
新Python枚举的开发以一系列补丁的形式进行。虽然我们投入了大量精力来支持旧枚举(而不推广它们),但仍然有可能存在某些情况下无法使用当前的Python枚举。为了避免人们设置环境标志完全禁用此功能,我们实现了一种方法,通过一组特定的标志逐步选择每个枚举函数的组合。
可能的枚举标志¶
这是用于控制Python枚举创建的所有标志的表格。
标志名称 |
值 |
|
---|---|---|
ENOPT_OLD_ENUM |
0x00 |
(错误) 自 PySide 6.6 起不再可能 |
ENOPT_NEW_ENUM |
0x01 |
(True) PySide 6.4 的默认值,完整实现 |
ENOPT_INHERIT_INT |
0x02 |
将所有枚举转换为IntEnum,并将标志转换为IntFlag |
ENOPT_GLOBAL_SHORTCUT |
0x04 |
重新添加全局枚举的快捷方式 |
ENOPT_SCOPED_SHORTCUT |
0x08 |
重新添加作用域枚举的快捷方式 |
ENOPT_NO_FAKESHORTCUT |
0x10 |
不要假装重命名(宽容模式) |
ENOPT_NO_FAKERENAMES |
0x20 |
不要伪造快捷方式(宽容模式) |
ENOPT_NO_ZERODEFAULT |
0x40 |
不使用零默认值(宽恕模式) |
ENOPT_NO_MISSING |
0x80 |
不允许枚举中存在缺失值 |
这样一组标志可以通过环境变量PYSIDE6_OPTION_PYTHON_ENUM
定义,或者在导入PySide6之前通过Python变量sys.pyside6_option_python_enum
设置。环境变量还支持通过使用ast.literal_eval
来支持任意的整数表达式。
ENOPT_OLD_ENUM (0x00)¶
此选项完全禁用新的枚举实现。 尽管这是一个有效的选项,但我们希望尽可能避免使用它。 目标是最终移除旧的实现。为了实现这一点, 我们将枚举实现的各个功能作为标志提供。 这样,如果用户报告问题,我们可能能够在相应扩展枚举支持之前提供临时解决方案。
ENOPT_NEW_ENUM (0x01)¶
在一个完美的世界里,没有人会选择除了这个默认设置之外的任何东西。不幸的是,现实并不总是如此。这就是为什么有以下标志。
最可能需要的标志¶
如果有错误,它们可能是以下情况:要么存在需要IntEnum的隐式假设,要么使用了不幸无法通过技巧替换的全局枚举。
ENOPT_INHERIT_INT (0x02)¶
当此标志被设置时,所有的enum.Enum/enum.Flag
类都会被转换为enum.IntEnum/enum.IntFlag
。这解决了切换到Python枚举时最可能的兼容性问题。旧的Shiboken枚举总是继承自int,但大多数Python枚举则不然。
这是Python开发者的决定,默认情况下不让枚举从int继承,因为不应该暗示任何顺序。在大多数情况下,可以通过使用value属性或更好的提升来避免从int继承:在期望int参数的函数中,不使用AnEnum.AnInstance.value
,你也可以在调用后通过AnEnum(int_arg)
将整数转换为枚举实例,并在比较中使用它。
然而,在某些情况下这是不可能的,PySide 中明确的支持根本不可用。在这些情况下,您可以使用此标志作为临时解决方案,直到我们实现替代方案。
ENOPT_GLOBAL_SHORTCUT (0x04)¶
在Python枚举实现的初期,我们继续支持Shiboken枚举的快捷行为:枚举常量被镜像到封闭作用域中。 这在后来的宽恕模式中被模仿。对于PySide类中的枚举类,这工作得很好,但对于直接在模块级别上的枚举类,没有好的方法来实现宽恕。
全局枚举隐藏错误的可能性不大,因为它们应该在导入期间就已经产生错误。但对于无法访问源代码的情况,您可以使用此标志来帮助自己。
标志值0x6很可能解决大多数问题。
完整性的标志¶
以下标志补充了Python枚举的描述。 它们本质上是为了更好地理解 实现,并使其完全透明和可定制。
ENOPT_SCOPED_SHORTCUT (0x08)¶
为了完整性,我们还支持了镜像作用域枚举,尽管这已经被宽恕模式所取代。如果你想尝试这个,请同时使用ENOPT_NO_FAKESHORTCUT标志(0x10),否则这个标志的效果将不可见。
ENOPT_NO_FAKERENAMES (0x10)¶
宽容模式模拟将Enum.Flag
类重命名为Shiboken的QFlags结构,这些结构有略微不同的名称。因此,当使用此类已废弃的名称时,系统会在内部将其替换为新的enum.Flag
结构。除非引发特殊的边界问题,否则这种替换应该有效。
要查看此重命名的效果,您可以使用此标志将其关闭。
ENOPT_NO_ZERODEFAULT (0x40)¶
作为宽容模式的一部分,Python枚举可以通过无参数调用来创建,尽管Python枚举在调用时实际上强制要求参数。
如果设置此标志以禁用它,可以检查效果。
ENOPT_NO_MISSING (0x80)¶
在某些情况下,Shiboken枚举使用缺失值。在enum.Flag
结构中,这是允许的,因为我们已经设置了FlagBoundary.KEEP
标志(参见enum.py
)。
普通的 enum.Enum
结构没有这个规定,但 enum
模块允许传递一个 _missing_
函数进行自定义。
我们处理这种情况的方法是创建一个新的假enum.Enum
类,具有相同的名称和一个无名的实例,并通过属性设置假装它具有相同的类型。以这种方式创建的额外实例被记录在类字典_sbk_missing_
中,以保留它们的身份。
如果你设置了这个标志,你会看到没有定义_missing_
函数的效果。