问题
Is there a way to tell pprint
in Python 3 not to split strings on whitespace? Python 2's pprint
did not do this. Can this behavior be disabled? I looked through the source for pprint
and it doesn't look like there's an option I saw for this.
Can I trick it somehow?
Here's an example of what I'm getting:
>>> PP.pprint("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ",width=-1,compact=True)
('ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ '
'ZZZZZ')
And here's what I want:
>>> PP.pprint("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ",width=-1,compact=True)
('ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ')
To clarify, I do want it to obey widths, just not for strings. So when I see eg:
PP.pprint(["ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZZZZZZZZZ","CATS"])
I want:
['ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZZZZZZZZZ',
'CATS']
Not:
['ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ '
'ZZZZZZZZZZZZZ',
'CATS']
回答1:
You could just set the width
option to a really large value, such as sys.maxsize
:
>>> import sys
>>> import pprint as PP
>>> PP.pprint("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ",width=sys.maxsize,compact=True)
'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ'
Setting width
to -1
has no special meaning.
The only other option is to subclass the PrettyPrinter()
class, and wrapping the _format()
method:
import sys
from pprint import PrettyPrinter
class NoStringWrappingPrettyPrinter(PrettyPrinter):
def _format(self, object, *args):
if isinstance(object, str):
width = self._width
self._width = sys.maxsize
try:
super()._format(object, *args)
finally:
self._width = width
else:
super()._format(object, *args)
NoStringWrappingPrettyPrinter().pprint(yourobject)
This sets the width to sys.maxsize
only for strings:
>>> NoStringWrappingPrettyPrinter().pprint(["ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ", "CATS"])
['ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ',
'CATS']
回答2:
It appears that you need to set the width to be the length of your string + 3 (for the quotes on either side and the newline) at an absolute minimum.
>>> x = 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ'
>>> PP.pprint(x, width=len(x))
'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ '
'ZZZZZ'
>>> PP.pprint(x, width=len(x) + 3)
'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ZZZZZ'
回答3:
Another approach, similar to that of Martijn Pieters, but which relies less on the internals of pprint
is to subclass PrettyPrinter
and override format.
Inside you can delegate to super().format
but in the result you can fake the length of strings, such that they won't be split. This relies on the output stream (e.g. sys.stdout
or StringIO()
) not looking at the string length.
class Python2PrettyPrinter(pprint.PrettyPrinter):
class _fake_short_str(str):
def __len__(self):
return 1 if super().__len__() else 0
def format(self, object, context, maxlevels, level):
res = super().format(object, context, maxlevels, level)
if isinstance(object, str):
return (self._fake_short_str(res[0]), ) + res[1:]
return res
from io import StringIO
assert StringIO().write(_fake_short_str('_' * 1000)) == 1000
Python2PrettyPrinter().pprint(["TEST " * 20] * 2)
# ['TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ',
# 'TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ']
The 100% clean way would be to modify the behavior of format
for all supported container classes, and substitute every string for a custom object which has the same representation.
来源:https://stackoverflow.com/questions/31485402/can-i-make-pprint-in-python3-not-split-strings-like-in-python2