格式化的Python字符串既不使用repr也不使用str发生了什么?

2024-09-29 21:27:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个枚举ResourceType,它继承自namedtupleEnum,并且我不覆盖任何地方的__str____repr__。格式化该枚举的实例时,意外地只得到未修饰的值,而不是repr()str()。这怎么可能?这叫什么

枚举详细信息(简化):

from enum import Enum, auto
from collections import namedtuple

class ResourceType(namedtuple('ResourceType', 'value ext required'), Enum):
    RGB = auto(), '.png', True

输出:

>>> repr(ResourceType.RGB)
"<ResourceType.RGB: ResourceType(value=<enum.auto object at 0x7f44b7d48d30>, ext='.png', required=True)>"

>>> str(ResourceType.RGB)
'ResourceType.RGB'

>>> f"{ResourceType.RGB}"
"ResourceType(value=<enum.auto object at 0x7f44b7d48d30>, ext='.png', required=True)"

最后一个值既不是repr()也不是str(),因此即使namedtuple提供了该字符串,为什么它也不提供str/repr


Tags: fromimporttrueautopngvaluerequiredenum
3条回答

现在Kemp和Daweo已经指出魔法是通过__format__发生的,我能够深入挖掘,事实上在Enum类中我们发现:

def __format__(self, format_spec):
    # mixed-in Enums should use the mixed-in type's __format__, otherwise
    # we can get strange results with the Enum name showing up instead of
    # the value

    # pure Enum branch
    if self._member_type_ is object:
        cls = str
        val = str(self)
    # mix-in branch
    else:
        cls = self._member_type_
        val = self._value_
    return cls.__format__(val, format_spec)

ResourceType也是一个混合的inEnum,这是由于namedtuple的继承性,因此对于__format__情况,调用被重定向到“ResourceType”namedtuple,只使用enum实例的值,该值通过约定/实现存储在_value_

在我的例子中,我希望ResourceType枚举在外部尽可能像一个枚举一样出现,尽管它也是一个namedtuple,因此我现在将其更改为:

class ResourceType(namedtuple('ResourceType', 'value ext required'), Enum):
    RGB = auto(), '.png', True
    def __format__(self, format_spec):
        return str.__format__(str(self), format_spec)

这完全等同于在Enum.__format__实现中强制执行“纯枚举分支”

什么叫什么

Enum.__format__的文档字符串在enum.py中声明它

Returns format using actual value type unless __str__ has been overridden.

以这种方式将对象插入f字符串时,它将调用^{}方法

from enum import Enum, auto
from collections import namedtuple

class ResourceType(namedtuple('ResourceType', 'value ext required'), Enum):
    RGB = auto(), '.png', True

    def __repr__(self):
        return "REPR"

    def __str__(self):
        return "STR"

    def __format__(self, format_spec):
        return "FORMAT"

print(repr(ResourceType.RGB))
print(str(ResourceType.RGB))
print(f"{ResourceType.RGB}")

输出

REPR
STR
FORMAT

相关问题 更多 >

    热门问题