支持f'{enum}' != str(enum) 对于具有 str mixin 的枚举,这是怎么回事?



下面,为什么str.__str__(似乎)优先于"更具体的";Mixin.BEEMixin.__str__Enum.__str__?

尽管Python的f-string文档说:

一般约定是,空格式规范产生的结果与对该值调用str()的结果相同。非空格式规范通常会修改结果。

到底发生了什么?

def format_vs_str(val):
formatted, stred = f'{val}', str(val)
if formatted != stred:
raise ValueError(f'{repr(formatted)} != {repr(stred)}')
return True

format_vs_str(1)  # True
format_vs_str('adsfa')  # True
Normal = Enum('Normal', {'BEE': 'BEE', 'C': 'CAT'})
format_vs_str(Normal.BEE) #  True
Mixin = Enum('Mixin', {'BEE': 'BEE', 'C': 'CAT'}, type=str)
format_vs_str(Mixin.BEE)  # ValueError: 'BEE' != 'Mixin.BEE'
Mixin.__str__(Mixin.BEE)  # 'Mixin.BEE'
Enum.__str__(Mixin.BEE)  # 'Mixin.BEE'
str.__str__(Mixin.BEE)  # 'BEE'

更古怪:

class Foo(str):
def __str__(self):
return 'my own str'
foo = Foo()
str(foo)  # 'my own str'
f'{foo}'  # 'my own str'
str.__str__(foo)  # '' ???

使用__format__代替__str__。在代码:

enum = Mixin.BEE
[f'{enum}', str(enum)]                 # ['BEE', 'Mixin.BEE']
# underneath, will call dunders:
[enum.__format__(''), enum.__str__()]  # ['BEE', 'Mixin.BEE']
# "proof", see: https://docs.python.org/3/library/dis.html#opcode-FORMAT_VALUE
import dis
dis.dis("f'{Mixin.BEE}'")
#  1           0 LOAD_NAME                0 (Mixin)
#              2 LOAD_ATTR                1 (BEE)
#              4 FORMAT_VALUE             0
#              6 RETURN_VALUE

相关内容

  • 没有找到相关文章

最新更新