提问人:Tobias Wilfert 提问时间:11/7/2023 最后编辑:wjandreaTobias Wilfert 更新时间:11/7/2023 访问量:75
为什么数据类偏爱__repr__而不是__str__?
Why does dataclass favour __repr__ over __str__?
问:
鉴于以下代码,我认为输出是有道理的,因为优先于输出,但是我对输出有点困惑,为什么它偏向于输出,有没有办法让类使用而不是 of 而不定义 for?(A)
__str__
__repr__
(B)
__repr__
__str__
__str__
__repr__
Foo
__str__
Bar
@dataclass()
class Foo():
def __repr__(self) -> str:
return "Foo::__repr__"
def __str__(self) -> str:
return "Foo::__str__"
@dataclass()
class Bar():
foo: Foo
f = Foo()
b = Bar(f)
print(f) # (A) Outputs: Foo::__str__
print(b) # (B) Outputs: Bar(foo=Foo::__repr__)
我偶然发现了这一点,因为我看到我的习惯实际上没有被使用,即使我删除了输出,输出仍然会是而不是。__str__
Foo
Bar
__repr__
(B)
Bar(foo=Foo())
Bar(foo=Foo::__str__)
答:
4赞
wim
11/7/2023
#1
在某种容器中呈现表示时,repr 优先于 str 是正常的,例如:
>>> print(f)
Foo::__str__
>>> print([f])
[Foo::__repr__]
repr 必须明确无误,例如要在此处查看数字和字符串之间的区别:
>>> from dataclasses import dataclass
>>> @dataclass
... class D:
... s: str
... n: int
...
>>> D('1', 1)
D(s='1', n=1)
我认为你不应该以这种方式覆盖,因为你偏离了 eval(repr(obj)) == obj
的“不成文规则”。Foo.__repr__
评论
2赞
Charles Duffy
11/7/2023
..._is_未成文?我依稀记得它被明确地写成(在 2.x 时代的某个地方),当人们不能遵守该约定时,使用箭头括号来明确表示所发出的内容是不可评估的。
1赞
wim
11/7/2023
据我所知,文档只说“对于许多类型,这个函数会尝试[这样做]......”,并且没有明确提供任何指导,建议用户定义的类型也应该这样做。
0赞
Learning is a mess
11/7/2023
@CharlesDuffy 我不认为有这样的规则,例如 sklearn 不遵守 Charles 提到的第一条规则,但在其不包含拟合状态的 repr 给出中也没有使用方括号。repr(PCA().fit(np.random.randn(10,10)))
PCA()
1赞
Barmar
11/7/2023
#2
这是容器的默认约定。它类似于列表、元组和字典的工作方式——它们用于元素值。repr()
评论
__str__
和__repr__
有什么区别?Bar
__str__
的情况下让类使用Foo
的__str__
而不是__repr__
?”,你为什么要这样做?如果你想有一个更最终用户友好的,你需要自己编写它。您是否知道默认为 因为该类没有 ?Bar
__str__
str(b)
repr(b)
__str__