2015-05-05 4 views
12

Ich versuchte pprint von pprint, aber sein Ausgang ist nur eine Zeile, es gibt keine mehrzeilige Ausgabe und keine Einrückung.Hübscher Druck named

+4

Können Sie ein Beispiel für das gewünschte Objekt um zu drucken und wie die gedruckte Ausgabe aussehen soll? – TigerhawkT3

+1

Was hast du erwartet? Wenn Sie mehr Kontrolle über die Ausgabe benötigen, erstellen Sie ein benutzerdefiniertes Objekt und definieren Sie '__repr__'. – jonrsharpe

Antwort

8

Ich benutze namedtuple _asdict Methode.

Aber es gibt eine OrderedDict das pprint nicht Einzug, so wandle ich es zu einem dict:

>>> Busbar = namedtuple('Busbar', 'id name voltage') 
>>> busbar = Busbar(id=102, name='FACTORY', voltage=21.8) 

Mit pprint und dict:

>>> from pprint import pprint 
>>> pprint(dict(busbar._asdict())) 
{'id': 102, 
'name': 'FACTORY', 
'voltage': 21.8} 
4

Die pprint Pretty in Python 3 ist viel erweiterbarer als es in Python 2 war. Sie könnten Ihren eigenen Drucker wie unten erstellen, um Methoden für das Objekt hinzuzufügen, das Sie handhaben möchten, ohne zu viel mit dem "privaten" Verfahren von pprint zu tun zu haben DS und Attribute.

Sie können ein Online Beispiel siehe hier: https://repl.it/HkDd/1

from io import StringIO 
import pprint 

class MyPrettyPrinter(pprint.PrettyPrinter): 
    def format_namedtuple(self, object, stream, indent, allowance, context, level): 
     # Code almost equal to _format_dict, see pprint code 
     write = stream.write 
     write(object.__class__.__name__ + '(') 
     object_dict = object._asdict() 
     length = len(object_dict) 
     if length: 
      # We first try to print inline, and if it is too large then we print it on multiple lines 
      inline_stream = StringIO() 
      self.format_namedtuple_items(object_dict.items(), inline_stream, indent, allowance + 1, context, level, inline=True) 
      max_width = self._width - indent - allowance 
      if len(inline_stream.getvalue()) > max_width: 
       self.format_namedtuple_items(object_dict.items(), stream, indent, allowance + 1, context, level, inline=False) 
      else: 
       stream.write(inline_stream.getvalue()) 
     write(')') 

    def format_namedtuple_items(self, items, stream, indent, allowance, context, level, inline=False): 
     # Code almost equal to _format_dict_items, see pprint code 
     indent += self._indent_per_level 
     write = stream.write 
     last_index = len(items) - 1 
     if inline: 
      delimnl = ', ' 
     else: 
      delimnl = ',\n' + ' ' * indent 
      write('\n' + ' ' * indent) 
     for i, (key, ent) in enumerate(items): 
      last = i == last_index 
      write(key + '=') 
      self._format(ent, stream, indent + len(key) + 2, 
         allowance if last else 1, 
         context, level) 
      if not last: 
       write(delimnl) 

    def _format(self, object, stream, indent, allowance, context, level): 
     # We dynamically add the types of our namedtuple and namedtuple like 
     # classes to the _dispatch object of pprint that maps classes to 
     # formatting methods 
     # We use a simple criteria (_asdict method) that allows us to use the 
     # same formatting on other classes but a more precise one is possible 
     if hasattr(object, '_asdict') and type(object).__repr__ not in self._dispatch: 
      self._dispatch[type(object).__repr__] = MyPrettyPrinter.format_namedtuple 
     super()._format(object, stream, indent, allowance, context, level) 

und es verwenden, etwa so:

from collections import namedtuple 

Segment = namedtuple('Segment', 'p1 p2') 
# Your own namedtuple-like class 
class Node: 
    def __init__(self, x, y, segments=[]): 
     self.x = x 
     self.y = y 
     self.segments = segments 

    def _asdict(self): 
     return {"x": self.x, "y": self.y, "segments": self.segments} 

    # Default repr 
    def __repr__(self): 
     return "Node(x={}, y={}, segments={})".format(self.x, self.y, self.segments) 

# A circular structure for the demo 
node = Node(0, 0) 
segments = [ 
    Segment(node, Node(1, 1)), 
    Segment(node, Node(2, 1)), 
    Segment(node, Node(1, 2, segments=[ 
     Segment(Node(2, 3), Node(1, 1)), 
    ])), 
] 
node.segments = segments 

pp = MyPrettyPrinter(indent=2, depth=2) 
pp.pprint(node) 

Ausgänge

Node(
    x=0, 
    y=0, 
    segments=[ Segment(
       p1=<Recursion on Node with id=139778851454536>, 
       p2=Node(x=1, y=1, segments=[])), 
       Segment(
       p1=<Recursion on Node with id=139778851454536>, 
       p2=Node(x=2, y=1, segments=[])), 
       Segment(
       p1=<Recursion on Node with id=139778851454536>, 
       p2=Node(x=1, y=2, segments=[...]))])