[issue7434] pprint doesn't know how to print a namedtuple
Raymond Hettinger
report at bugs.python.org
Sat Dec 5 08:41:20 CET 2009
Raymond Hettinger <rhettinger at users.sourceforge.net> added the comment:
I agree with you that pprint needs to be rewritten to make it more
extensible.
I do not see a straight-forward way of handling your feature request.
First, namedtuple() is a factory function and is not itself a class, so
there is no standard way to recognize one. Essentially, a named tuple
is concept (any class that supported both sequence behavior and
attribute access is a named tuple, for example the time structure is a
named tuple but not created by the collections.namedtuple() factory
function, instead is a C structseq which has substantially similar
characteristics). This means that pprint has no reliable way to tell if
one of its arguments is a named tuple.
Second, collections.namedtuple() is intentionally designed to let the
user override the default __repr__() method (see an example in the
namedtuple docs). That means that pprint cannot know in advance how a
named tuple is supposed to display.
At best, I can imagine that pprint() grows the ability to print a
multi-line repr (as specified by the object itself) but indented to a
level controlled by pprint(). The pprint() function would scan the repr
for newlines and replace them with a newline followed by the appropriate
number of spaces.
For example:
>>> class Point(namedtuple('Point', 'x y z')):
... 'Point with a multi-line repr'
... def __repr__(self):
... return 'Point(\n x=%r,\n y=%r,\n z=%r\n
)' % self
>>> Point(3,4,5)
Point(
x=3,
y=4,
z=5
)
>>> pprint([Point(3,4,5), Point(6,7,8)])
[Point(
x=3,
y=4,
z=5
),
Point(
x=6,
y=7,
z=8
)
]
Alternatively, the pprint module could introduce a new magic method to
support multi-line reprs when the repr itself it too long fit in a
single line:
class MyList(list):
... def __multirepr__(self):
... 'Return a list of strings to pprint'
... return Multi(head = 'Mylist([',
... body = [str(x).upper() for x in self],
... tail = '])
>>> pprint(MyList(['now', 'is', 'the', 'time', 'for']), width=15)
MyList(['NOW',
'IS',
'THE',
'TIME',
'FOR',
])
In summary, there are several ways to approach this problem but they are
centered on building-out pprint(), not on changing collections.namedtuple().
----------
assignee: rhettinger ->
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue7434>
_______________________________________
More information about the Python-bugs-list
mailing list