Jon*_*ung 4 python string recursion escaping repr
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)
Run Code Online (Sandbox Code Playgroud)
我希望此代码打印:
this
should
all
be
on
separate
lines[this
should
all
be
on
separate
lines[this
should
all
be
on
separate
lines]]
Run Code Online (Sandbox Code Playgroud)
或类似的东西,但它打印
this
should
all
be
on
separate
lines["this\nshould\nall\nbe\non\nseparate\nlines['this\\nshould\\nall\\nbe\\non\\nseparate\\nlines[]']"]
Run Code Online (Sandbox Code Playgroud)
也就是说,当我尝试将一个对象转换为字符串时,它已经在__repr__同一个类的另一个对象的方法中,它会将换行符转换为\n,如果我进一步嵌套它,它会导致\\n,每次我嵌套它都会添加转义序列前的附加反斜杠。
阅读完这个问题后,似乎该__repr__方法认为我实际上想要两个字符\and n,但我不想要:我想要转义序列\n。有什么方法可以覆盖它并强制它将其解释为换行符而不是两个单独的字符?
问题是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'"
Run Code Online (Sandbox Code Playgroud)
您遇到这种情况是因为您对列表的__repr__调用str和str列表的 使用repr( not str ) 在列表中的每个项目上:
>>> print('First line\nSecond line')
First line
Second line
>>> print(['First line\nSecond line'])
['First line\nSecond line']
Run Code Online (Sandbox Code Playgroud)
请注意,\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
Run Code Online (Sandbox Code Playgroud)
然后你print(myClass)给出你想要的结果。
| 归档时间: |
|
| 查看次数: |
2734 次 |
| 最近记录: |