为什么Python 3的PrettyPrinter与Python 2的行为不同,我如何获得相同的行为?

时间:2021-07-19 18:06:50

When I try running this code:

当我尝试运行此代码时:

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']))

I get a different output in Python 3 (['x']) than I get in Python 2 ([x]).

我在Python 3(['x'])中得到的输出不同于Python 2([x])。

Why is this, and how do I get the same behavior as in Python 2?

为什么会这样,我如何获得与Python 2相同的行为?

1 个解决方案

#1


2  

This is how Python 3’s internal _format function works:

这就是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)

As you can see, if the the output of _repr fits into a single line, then no custom logic for generating the repr is used. self._repr delegates to self.format, which essentially just does a more complex repr(). So this is just called once if the output fits in a single line; otherwise, the output is not used but the (here: sequence) element is split into multiple parts, and the logic is again invoked for subelements.

如您所见,如果_repr的输出适合单行,则不会使用用于生成repr的自定义逻辑。 self._repr委托给self.format,它实际上只是做一个更复杂的repr()。因此,如果输出适合单行,则只调用一次;否则,不使用输出,但将(here:sequence)元素拆分为多个部分,并再次为子元素调用逻辑。

In comparison, Python 2’s _format implements a completely custom logic at any stage, always invoking the custom formatter for all subelements in lists. That’s why your trigger works in Python 2 but does not in Python 3.

相比之下,Python 2的_format在任何阶段都实现了一个完全自定义的逻辑,总是为列表中的所有子元素调用自定义格式化程序。这就是为什么你的触发器在Python 2中起作用但在Python 3中不起作用的原因。

Unfortunately, I don’t see any simple way to hook into this without replicating a lot of the logic that’s in the new Python 3 implementation.

不幸的是,我没有看到任何简单的方法来解决这个问题而不复制新Python 3实现中的许多逻辑。

#1


2  

This is how Python 3’s internal _format function works:

这就是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)

As you can see, if the the output of _repr fits into a single line, then no custom logic for generating the repr is used. self._repr delegates to self.format, which essentially just does a more complex repr(). So this is just called once if the output fits in a single line; otherwise, the output is not used but the (here: sequence) element is split into multiple parts, and the logic is again invoked for subelements.

如您所见,如果_repr的输出适合单行,则不会使用用于生成repr的自定义逻辑。 self._repr委托给self.format,它实际上只是做一个更复杂的repr()。因此,如果输出适合单行,则只调用一次;否则,不使用输出,但将(here:sequence)元素拆分为多个部分,并再次为子元素调用逻辑。

In comparison, Python 2’s _format implements a completely custom logic at any stage, always invoking the custom formatter for all subelements in lists. That’s why your trigger works in Python 2 but does not in Python 3.

相比之下,Python 2的_format在任何阶段都实现了一个完全自定义的逻辑,总是为列表中的所有子元素调用自定义格式化程序。这就是为什么你的触发器在Python 2中起作用但在Python 3中不起作用的原因。

Unfortunately, I don’t see any simple way to hook into this without replicating a lot of the logic that’s in the new Python 3 implementation.

不幸的是,我没有看到任何简单的方法来解决这个问题而不复制新Python 3实现中的许多逻辑。