发生了什么?

hujrc8aj  于 2021-09-13  发布在  Java
关注(0)|答案(3)|浏览(295)

我有一个枚举 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?

yuvru6vn

yuvru6vn1#

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

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
gv8xihay

gv8xihay2#

现在肯普和达维奥已经指出,魔术正在通过 __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` 由于的继承,是混合在枚举中的 `namedtuple` 同样如此,对于 `__format__` 在这种情况下,调用被重定向到“resourcetype” `namedtuple` 仅使用存储在中的枚举示例的值 `_value_` 按惯例/执行。
就我而言,我想要 `ResourceType` enum在外部看起来尽可能像一个enum,尽管它也是一个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__` 实施
pod7payv

pod7payv3#

这叫什么?
它是 Enum.__format__ 其在enum.py中的文档字符串声明
使用实际值类型返回格式,除非 __str__ 已被覆盖。

相关问题