Python - 嵌套的 __repr__ 将换行符恢复为“\\n”

Posted

技术标签:

【中文标题】Python - 嵌套的 __repr__ 将换行符恢复为“\\\\n”【英文标题】:Python - nested __repr__ reverts newline to "\\n"Python - 嵌套的 __repr__ 将换行符恢复为“\\n” 【发布时间】:2016-04-05 02:24:55 【问题描述】:
class MyClass:
    def __init__(self):
        self.list_ = []
    def __repr__(self):
        return '\n'.join(['this','should','all','be','on','separate','lines']) + str([str(list_val) for list_val in self.list_])

myClass = MyClass()
myClass.list_.append(MyClass())
myClass.list_[0].list_.append(MyClass())
print(myClass)

我希望这段代码能打印出来:

this
should
all
be
on
separate
lines[this
should
all
be
on
separate
lines[this
should
all
be
on
separate
lines]]

或类似的东西,但它会打印

this
should
all
be
on
separate
lines["this\nshould\nall\nbe\non\nseparate\nlines['this\\nshould\\nall\\nbe\\non\\nseparate\\nlines[]']"]

也就是说,当我尝试在同一类的另一个对象的__repr__ 方法中将一个对象转换为字符串时,它会将换行符转换为\n,如果我进一步嵌套它会导致\\n,每次我嵌套它时,它都会在转义序列之前添加一个额外的反斜杠。

看了this question之后,好像__repr__方法认为我其实想要\n这两个字符,但是我不:我想要转义序列\n。有没有办法覆盖它并强制它解释为换行符而不是两个单独的字符?

【问题讨论】:

【参考方案1】:

问题在于字符串的repr 将特殊字符转换为转义序列。这意味着如果您在带有特殊字符的字符串上递归调用 repr,反斜杠将会堆积:

>>> print("First line\nSecond line")
First line
Second line
>>> print(repr("First line\nSecond line"))
'First line\nSecond line'
>>> print(repr(repr("First line\nSecond line")))
"'First line\\nSecond line'"

您遇到这种情况是因为您的 __repr__ 在列表中调用 str,而列表的 str 在列表:

>>> print('First line\nSecond line')
First line
Second line
>>> print(['First line\nSecond line'])
['First line\nSecond line']

注意\n 出现在这里,就像在第一个示例中对字符串本身调用repr 所做的一样。这是因为列表在其内容上调用 repr 以显示自己。

所以通过str([...]),您在列表的内容上调用repr,这意味着您正在递归调用repr 您的嵌套对象,这意味着反斜杠堆积如您所见。

如果你想避免这种情况,你需要避免在嵌套对象上调用 repr。您可以通过使用join 手动制作一个字符串来做到这一点,类似于您已经做过的,而不是在列表上调用str

def __repr__(self):
    innerRepr = '['+'\n'.join(str(list_val) for list_val in self.list_) + ']' if self.list_ else ''
    return '\n'.join(['this','should','all','be','on','separate','lines']) + innerRepr

那么你的print(myClass) 会给出你想要的结果。

【讨论】:

哇,惊人的答案——难度级别 11。

以上是关于Python - 嵌套的 __repr__ 将换行符恢复为“\\n”的主要内容,如果未能解决你的问题,请参考以下文章

python学习之__str__,__repr__

python模块可以有__repr__吗?

Python __repr__ 用于所有成员变量

Python __repr__ 和无

python __str__ , __repr__区别

Python中__str__和__repr__的区别