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实现中的许多逻辑。