从旧式到新式枚举的快速更新的安全性
从旧式到新式枚举的快速更新的安全性
在项目中,相比于NewBreakfast
风格的枚举,假设我们仍然有OldBreakfast
风格的枚举,这是Python2时代的遗留物。\n
from enum import Enum class OldBreakfast: HAM = 0x00 EGGS = 0x01 PANCAKES = 0x02 class NewBreakfast(Enum): HAM = 0x00 EGGS = 0x01 PANCAKES = 0x02 def eat(): food1 = OldBreakfast.HAM food2 = NewBreakfast.HAM print(food1) print(food2) eat()
\n从上面的代码中的eat()
函数中可以看出,从“旧”方式迁移到“新”方式的一个好处是,当进行单步调试或打印输出时,可以直接看到正在吃的食物,而无需返回代码并进行反向映射。\n令人愉快的是,将枚举更新为新的风格只需要进行非常有限的操作。特别是,只需要对枚举本身进行定义。其他所有的操作都会自动完成。\n这个最后的陈述是否准确?有没有需要注意的陷阱?\n相关链接:PEP435\n1\n2\n3\n4\n5
从旧式枚举(OldBreakfast)到新式枚举(NewBreakfast)的快速更新的安全性问题出现的原因是为了调试的方便性。通过在PyCharm中设置断点,我们可以看到使用了从Enum派生的枚举类型的值更具信息性。这意味着我们不需要回头查看代码,就可以知道food2的值是NewBreakfast.HAM。而如果使用旧式枚举,我们需要回头查看代码才能知道food1的值是0。
为了解决这个问题,我们可以对旧式枚举进行快速更新到新式枚举的风格。这样做可以提高代码的可读性和调试的便利性。
以下是快速更新旧式枚举到新式枚举的示例代码:
from enum import Enum class NewBreakfast(Enum): HAM = 1 EGG = 2 BACON = 3 class OldBreakfast: HAM = 0 EGG = 1 BACON = 2 # 快速更新旧式枚举到新式枚举 NewBreakfast.__members__.update(OldBreakfast.__dict__) # 使用新式枚举 food1 = NewBreakfast.HAM food2 = NewBreakfast.EGG print(food1) # 输出:NewBreakfast.HAM print(food2) # 输出:NewBreakfast.EGG
通过以上更新代码,我们可以在调试过程中更方便地查看枚举类型的值,而无需回头查看代码。这提高了代码的可读性和调试的便利性。
问题的出现原因是在将旧的枚举代码替换为新的枚举代码时,会导致安全性问题。解决方法是使用IntEnum
替代Enum
,以确保枚举值的安全性。
当替换旧的枚举代码时,可能需要使用IntEnum
(或StrEnum
等)。例如:
>>> OldBreakfast.HAM == 0 True >>> NewBreakfast.HAM == 0 False
但是:
>>> IntBreakfast.HAM == 0 True
我明白了。很好。但我认为在代码中进行常量测试的任何实例都是一个缺陷,并且这是一个很好的机会将它们揭示出来并删除它们。在这个意义上,NewBreakfast具有优势,虽然是一个奇怪的优势,因为人们有可能通过失败的测试而不是晦涩的崩溃来找到它们的位置。