我正在开发的代码库中使用的Python解释器版本最近已从Python 3.7更新到3.9。
当执行一些用 Python 编写的工具时,开始出现一些与标题中类似的新警告。
我广泛搜索了网络,阅读了3.10 中的新增功能,但尚未找到其确切含义的答案,以及我可以采取哪些可能的操作来解决它。当然,我可以选择 grep CPython 的源代码,但如果可能的话我宁愿避免它。
该警告似乎预示着班级成员的知名度会发生变化。有问题的代码不是我写的。原作者(当然)不再可用。就我个人而言,我从不使用下划线成员来试图影响他们的可见性。
警告周围的代码如下所示:
class Cmd(Enum):
...
@classmethod
def __call_set(cls, # << Here the warning
...):
...
将属性写成这样:
_attr
使其成为 private 属性,__attr
使其成为 protected 属性。此弃用警告似乎表明相关属性将在 3.10 中设为“不”私有且“不”受保护。
TL;博士
在 3.10 中它们不会有下划线,并且它们将完全可见。
这与
enum
Python
在 Python 3.11 之前,你可以这样做:class CarState(Flag):
DRIVING = auto()
STOPPED = auto()
# Parked should entail Stopped
# but I do not want a exposed __parked variable, and hide it to avoid its usage
__parked = auto()
PARKED = __parked | STOPPED
<3.11如果你想列出所有枚举,你可以这样做:
>>> list(VehicleState)
[<VehicleState.DRIVING: 1>,
<VehicleState.STOPPED: 2>,
<VehicleState._VehicleState__parked: 4>,
<VehicleState.PARKED: 6>]
私有变量是枚举的一部分
Python 3.11+
上面的代码将不再起作用class CarState(Flag):
DRIVING = auto()
STOPPED = auto()
# Parked should entail Stopped
# but I do not want a exposed __parked variable, and hide it to avoid its usage
__parked = auto()
PARKED = __parked | STOPPED
TypeError: unsupported operand type(s) for |: 'auto' and 'int'
为什么?因为
__parked = auto()
不会被转换为枚举,因此它不能用作一个
>>> VehicleState._VehicleState__parked
auto(_auto_null)
class VehicleState(Flag):
DRIVING = auto()
STOPPED = auto()
# Use only one underscore -> private Enum
_parked = auto()
# Double underscore cannot be used with auto()
__IS_FAST = 8
SPEEDING = DRIVING | __IS_FAST
但是这限制了
list
的使用
>>> list(VehicleState)
[<VehicleState.DRIVING: 1>, <VehicleState.STOPPED: 2>, <VehicleState._parked: 4>]
>>> VehicleState._member_map_
{'DRIVING': <VehicleState.DRIVING: 1>,
'STOPPED': <VehicleState.STOPPED: 2>,
'_parked': <VehicleState._parked: 4>,
'PARKED': <VehicleState.PARKED: 6>,
'SPEEDING': <VehicleState.SPEEDING: 9>}