为什么 Python 3 的 PrettyPrinter 与 Python 2 的行为不同,我如何获得相同的行为?
Why is Python 3's PrettyPrinter behaving differently from Python 2's, and how do I get the same behavior?
当我尝试 运行 这个代码时:
from pprint import PrettyPrinter
class MyPrettyPrinter(PrettyPrinter):
def __init__(self, *args, **kwargs):
PrettyPrinter.__init__(self, *args, **kwargs)
def format(self, object, context, maxlevels, level):
(repr, readable, recursive) = PrettyPrinter.format(self, object, context, maxlevels, level)
return (type(repr)(object), readable, recursive) if isinstance(object, str) else (repr, readable, recursive)
print(MyPrettyPrinter().pformat(['x']))
我 get a different output in Python 3 (['x']
) than I get 在 Python 2 ([x]
).
为什么会这样,如何获得与 Python 2 相同的行为?
这就是 Python 3 的内部 _format
函数的工作原理:
def _format(self, object, stream, indent, allowance, context, level):
# …
rep = self._repr(object, context, level - 1)
max_width = self._width - 1 - indent - allowance
sepLines = len(rep) > max_width
if sepLines:
# … custom repr logic
write(rep)
如您所见,如果 _repr
的输出适合一行,则不会使用生成 repr 的自定义逻辑。 self._repr
委托给 self.format
,这实际上只是做了一个更复杂的 repr()
。因此,如果输出适合一行,则只调用一次;否则,不使用输出,但(此处:序列)元素被分成多个部分,并再次为子元素调用逻辑。
相比之下,Python 2 的 _format
在任何阶段都实现了完全自定义的逻辑,始终为列表中的所有子元素调用自定义格式化程序。这就是为什么您的触发器在 Python 2 中有效但在 Python 3 中无效的原因。
不幸的是,如果不复制新 Python 3 实现中的大量逻辑,我看不出有任何简单的方法可以连接到此。
当我尝试 运行 这个代码时:
from pprint import PrettyPrinter
class MyPrettyPrinter(PrettyPrinter):
def __init__(self, *args, **kwargs):
PrettyPrinter.__init__(self, *args, **kwargs)
def format(self, object, context, maxlevels, level):
(repr, readable, recursive) = PrettyPrinter.format(self, object, context, maxlevels, level)
return (type(repr)(object), readable, recursive) if isinstance(object, str) else (repr, readable, recursive)
print(MyPrettyPrinter().pformat(['x']))
我 get a different output in Python 3 (['x']
) than I get 在 Python 2 ([x]
).
为什么会这样,如何获得与 Python 2 相同的行为?
这就是 Python 3 的内部 _format
函数的工作原理:
def _format(self, object, stream, indent, allowance, context, level):
# …
rep = self._repr(object, context, level - 1)
max_width = self._width - 1 - indent - allowance
sepLines = len(rep) > max_width
if sepLines:
# … custom repr logic
write(rep)
如您所见,如果 _repr
的输出适合一行,则不会使用生成 repr 的自定义逻辑。 self._repr
委托给 self.format
,这实际上只是做了一个更复杂的 repr()
。因此,如果输出适合一行,则只调用一次;否则,不使用输出,但(此处:序列)元素被分成多个部分,并再次为子元素调用逻辑。
相比之下,Python 2 的 _format
在任何阶段都实现了完全自定义的逻辑,始终为列表中的所有子元素调用自定义格式化程序。这就是为什么您的触发器在 Python 2 中有效但在 Python 3 中无效的原因。
不幸的是,如果不复制新 Python 3 实现中的大量逻辑,我看不出有任何简单的方法可以连接到此。