惊讶于 f'{enum}' != string(enum) 对于具有字符串混合的枚举,这是怎么回事?
Suprised that f'{enum}' != str(enum) for Enums that have a str mixin, What's going on?
下面,为什么 str.__str__
(似乎)优先于“更具体”的 Mixin.__str__
和 Enum.__str__
对于 Mixin.BEE
?
尽管 Python docs on f-strings 说:
A general convention is that an empty format specification produces the same result as if you had called str()
on the value. A non-empty format specification typically modifies the result.
引擎盖下发生了什么?
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
下面,为什么 str.__str__
(似乎)优先于“更具体”的 Mixin.__str__
和 Enum.__str__
对于 Mixin.BEE
?
尽管 Python docs on f-strings 说:
A general convention is that an empty format specification produces the same result as if you had called
str()
on the value. A non-empty format specification typically modifies the result.
引擎盖下发生了什么?
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