Python 3.11在去年末发布。通常,有beaucoup de nouveautés。一个部分比其他部分更吸引了我的Å:有beaucoup de changements et d'ajouts sur les enums!好的,速度是我正在寻找如何做的事情,我看到了Python 3.11精确带来了此功能...更新了我的解释器以测试â!
在本文中,我向您介绍了最有前途的消息。
3.11:enum
模块的重要版本
koude0模块出现在version 3.4和PEP 435的含义以来非常稳定。
出于文档的目的,我们看到:
版本3.6中的新事物:
Flag
,IntFlag
,auto
版本3.11:
StrEnum
,EnumCheck
,ReprEnum
,FlagBoundary
,FlagBoundary
,property
,member
,nonmember
,nonmember
,global_enum
,show_flag_values
版本3.11是一个带来许多新版本的版本。列出了9个以文档目的列出的,但是下面有10áµ:verify()
。在现实生活中,la documentation est loin d'être parfaite,但我们这样做。
愤怒的街道
为了娱乐,我致力于在愤怒的街道上使用基本示例。什么 ?!你不知道愤怒的街道吗?但是很快就匆匆忙忙的agrandir您的流行文化!
在Python 3.11之前可以做什么
如果您想列出Rage 2的街道级别,则可以从Python 3.4:
中制作这样的数字
class Stages(Enum):
DOWNTOWN = 1
BRIDGE_CONSTRUCTION = 2
AMUSEMENT_PARK = 3
STADIUM = 4
# ... et plusieurs autres encore !
他们非常宽容,例如,我们可以做类似的事情:
class Stages(Enum):
DOWNTOWN = 1
BRIDGE_CONSTRUCTION = 2
AMUSEMENT_PARK = 'three'
STADIUM = [4]
因此,可以具有不同类型的值。 â在某些情况下可以实用,但是我们想制作值类型,如我们的示例中,每个级别对应一个数字。正是由于这个原因,IntEnum
已引入Python 3.6:
class Stages(IntEnum):
DOWNTOWN = 1
BRIDGE_CONSTRUCTION = 2
AMUSEMENT_PARK = 3
STADIUM = 'four'
我们在ex -cation中获得一个例外:ValueError: invalid literal for int() with base 10: 'four'
。
请注意,如果我们有STADIUM = '4'
(请注意4个简单引号在4左右),则代码可行。实际上,正如例外表明的那样,IntEnum
使用int()
获取该值,事实证明该int('4') == 4
。因此,我们可以用作 initializer 一个提供def __int__(self) -> int
螨的类的实例。
IntEnum
实际上是“ 混合枚举”。 混合枚举的原理是使所需类型和enum
的(多个)外壳。这对我的鹅来说不是很好的纪录片,但是在"Enum HOWTO"中有解释(ici和一些là)。因此,我们获得了一个数字,其值一定是相同类型的T
。
在这些提醒之后,我们将介绍以下版本3.11的更改。
ReprEnum
如果我们听到ReprEnum
而不是Enum
,我们相信一个老年人的转换为 string 的价值类型。 documentation占上风:
ReprEnum
使用Enum
的repr()
,但是混合数据类型的str()
。(...)
从
ReprEnum
继承来保留混合数据类型的str()
/format()
,而不是使用Enum
-defaultstr()
。< / p>
IntEnum
s的显示改变了ReprEnum
的原因
What’s New In Python 3.11告诉我们:
将
IntEnum
(...)更改为现在继承的逆逆因,因此他们的str()
输出现在与format()
匹配(str(AnIntEnum.ONE)
和format(AnIntEnum.ONE)
return'1'
,而在str(AnIntEnum.ONE)
返回'AnIntEnum.ONE'
。
让我们看一下它给我们的Stages(IntEnum)
的数量:
print('member\t', Stages.DOWNTOWN)
print('name\t', Stages.DOWNTOWN.name)
print('value\t', Stages.DOWNTOWN.value)
print('str()\t', str(Stages.DOWNTOWN))
print('repr()\t', repr(Stages.DOWNTOWN))
print('f-str\t', f'{Stages.DOWNTOWN}')
A 3.10:
member Stages.DOWNTOWN
name DOWNTOWN
value 1
str() Stages.DOWNTOWN
repr() <Stages.DOWNTOWN: 1>
f-str 1
3.11中的修改显示:
member 1
name DOWNTOWN
value 1
str() 1
repr() <Stages.DOWNTOWN: 1>
f-str 1
就个人而言,我发现它更合乎逻辑,但是此更改可能会对现有代码产生后果!
StrEnum
,像IntEnum
一样,但是用丁字裤
我们通常需要制作一个仅包含 thongs 的数字,例如列出游戏中的字符:
class Characters(StrEnum):
AXEL = 'Axel Stone'
BLAZE = 'Blaze Fielding'
MAX = 'Max Thunder'
SKATE = 'Eddie "Skate" Hunter'
StrEnum
he ReprEnum
,这意味着print(str(Characters.BLAZE))
和print(f'{Characters.BLAZE}')
显示Blaze Fielding
。如果我们完成了Characters(Enum)
,则显示会给Characters.BLAZE
。至于IntEnum
,我找到了这个逻辑显示。
我们可以将auto()
与StrEnum
:
class Characters(StrEnum):
# ...
SKATE = auto()
str(Characters.SKATE))
将是skate
。
有可能在Python 3.11之前制作一个StrEnum
,并具有简单的枚举,但打字不太强。例如,我们可以做:
class Characters(str, Enum):
AXEL = 'Axel Stone'
BLAZE = 'Blaze Fielding'
MAX = 'Max Thunder'
SKATE = 8
那是残酷的。确实,可以使用str(8)
从8开始构建A thong 。它没有在文档中说,但是我们可以看一下StrEnum
在enum.py
中的含义,并且我们看到制造商被降低并明确地与isinstance(..., str)
进行了静脉。 IntEnum
并非如此。
@verify
更有可能
@unique
自从检测到enum
模块以来就已经被阻止了,并可以确保每个成员都有一个……唯一! ð
完成游戏的水平并确保它们都有不同的数字是非常好的。示例:
@unique
class Stages(IntEnum):
DOWNTOWN = 1
BRIDGE_CONSTRUCTION = 2
AMUSEMENT_PARK = 3
STADIUM = 3
此代码是一个例外:ValueError: duplicate values found in <enum 'Stages'>: STADIUM -> AMUSEMENT_PARK
。
一个新的宣布,koude69,出现在3.11中:
专门用于枚举的
class
装饰师。EnumCheck
的成员用于指定应在装饰的枚举上检查哪些约束。
因此,他会吸收koude6s的参数:
Enumcheck 包含
verify()
装饰器使用的选项,以确保各种约束;失败的约束导致ValueError
。
目前可以使用koude79,koude80和koude81。 @verify(UNIQUE)
是哪个
我们可以在参数上花几个标志,这非常适合我们的示例:
@verify(UNIQUE, CONTINUOUS)
class Stages(IntEnum):
DOWNTOWN = 1
BRIDGE_CONSTRUCTION = 2
AMUSEMENT_PARK = 3
STADIUM = 5
有一个例外,我们缺少一个值:ValueError: invalid enum 'Stages': missing values 4
。
使成员可以在整个名称空间中访问
要访问会员,您通常必须通过类:Stages.STADIUM
。
在某些情况下(以及随之而来的名称冲突的通风风险),您可能需要直接使用STADIUM
。从Python 3.11可以使用@global_enum
注释您的课程。
控制什么是会员,什么不是成员
两个nouveaux décorateurs允许我们明确控制数字中的成员,什么不是:
@enum.member
用于枚举的装饰器:其目标将成为成员。
@enum.nonmember
用于枚举的装饰器:其目标不会成为会员。
当我们谈论一个数字成员时,我们正在谈论他的不同价值观。
这个@member
鹿器非常实用,可以最终得到许多值的数字。
对于Rage 2的街道,我们需要角色可以做的3个基本动作中的许多。功能是实现动作的好人。顺便说一句,在Enum
的de -rightere类中完成的函数是 static方法。因此,以下代码无法完成我们想要的事情,因为它会在没有价值的情况下创造无尽的性:
class Controls(Enum):
def special_move():
print('Special move, massive damage!')
def attack():
print('Attack? OK! Punch!')
def jump():
print('The floor is lava! Jump!')
print(list(Controls))
Controls.attack()
此海报代码:
[]
Attack? OK! Punch!
要纠正这一点,只需注释函数:
class Controls(Enum):
@member
def special_move():
print('Special move, massive damage!')
@member
def attack():
print('Attack? OK! Punch!')
@member
def jump():
print('The floor is lava! Jump!')
print(list(Controls))
Controls.attack.value()
我们这次得到了:
[<Controls.special_move: <function Controls.special_move at 0x0000015B0080AD40>>,
<Controls.attack: <function Controls.attack at 0x0000015B00778680>>,
<Controls.jump: <function Controls.jump at 0x0000015B00822200>>]
Attack? OK! Punch!
完美!请注意,Controls.attack
不是 calblable (因为它是数字的成员),并且必须将.value
用于访问该功能。
相反,如果您希望给定的一个在班上静态,则必须使用@nonmember()
。语法有点令人惊讶(我发现),官方文档没有举例说明。这是道路的小孩子:
class Characters(StrEnum):
playable = nonmember(True)
AXEL = 'Axel Stone'
BLAZE = 'Blaze Fielding'
MAX = 'Max Thunder'
SKATE = 'Eddie "Skate" Hunter'
print(Characters.playable)
与往常一样,在Python中,可以通过其成员访问类字段,因此您可以使用Characters.SKATE.playable
。
结论
此版本的Python 3.11有很多新的条目!当您的主要语言是C ++时,enumérations确实非常基本,您就像一个孩子在糖果店里!我很遗憾,即使是文档不贴上的(某些功能也很糟糕,甚至没有纪录片),而且太奇怪的是(例如show_flag_values(),它不会添加到__all__
中,并且其使用真的很差)。我们敢打赌,它将在下一个版本中链接,并在enum
中利用此补充功率!