Disabling sorting mechanism in pprint output

后端 未结 4 1347
鱼传尺愫
鱼传尺愫 2020-12-20 12:01

I have big dictionary which I`m printing for viewing with prettyprint, but how I can keep formatting but kill sorting mechanism in pprint?

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-20 12:17

    You can subclass PrettyPrinter and remove the sorted(object.items()) from _pprint_dict.

    NOTE: this code is Python 3.5+

    # unsorted_pprint.py
    
    from pprint import PrettyPrinter, _builtin_scalars, _recursion
    
    __all__ = [
        'UnsortedPrettyPrinter',
        'pprint2',
        'pformat2',
    ]
    
    
    class UnsortedPrettyPrinter(PrettyPrinter):
        """Pretty printer that retains original dict ordering
        """
        def __init__(self, *args, **kwargs):
            super().__init__()
    
            self._dispatch = {
                **self._dispatch,
                dict.__repr__: self._pprint_dict,
            }
    
        @staticmethod
        def _pprint_dict(self, object, stream, indent, allowance, context, level):
            write = stream.write
            write('{')
            if self._indent_per_level > 1:
                write((self._indent_per_level - 1) * ' ')
            length = len(object)
            if length:
                items = object.items()
                self._format_dict_items(items, stream, indent, allowance + 1,
                                        context, level)
            write('}')
    
        def format(self, object, context, maxlevels, level):
            """Format object for a specific context, returning a string
            and flags indicating whether the representation is 'readable'
            and whether the object represents a recursive construct.
            """
            return self._safe_repr(object, context, maxlevels, level)
    
        def _safe_repr(self, object, context, maxlevels, level):
            typ = type(object)
            if typ in _builtin_scalars:
                return repr(object), True, False
    
            r = getattr(typ, "__repr__", None)
            if issubclass(typ, dict) and r is dict.__repr__:
                if not object:
                    return "{}", True, False
                objid = id(object)
                if maxlevels and level >= maxlevels:
                    return "{...}", False, objid in context
                if objid in context:
                    return _recursion(object), False, True
                context[objid] = 1
                readable = True
                recursive = False
                components = []
                append = components.append
                level += 1
                saferepr = self._safe_repr
                items = object.items()
                for k, v in items:
                    krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
                    vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
                    append("%s: %s" % (krepr, vrepr))
                    readable = readable and kreadable and vreadable
                    if krecur or vrecur:
                        recursive = True
                del context[objid]
                return "{%s}" % ", ".join(components), readable, recursive
    
            if (issubclass(typ, list) and r is list.__repr__) or \
                (issubclass(typ, tuple) and r is tuple.__repr__):
                if issubclass(typ, list):
                    if not object:
                        return "[]", True, False
                    format = "[%s]"
                elif len(object) == 1:
                    format = "(%s,)"
                else:
                    if not object:
                        return "()", True, False
                    format = "(%s)"
                objid = id(object)
                if maxlevels and level >= maxlevels:
                    return format % "...", False, objid in context
                if objid in context:
                    return _recursion(object), False, True
                context[objid] = 1
                readable = True
                recursive = False
                components = []
                append = components.append
                level += 1
                for o in object:
                    orepr, oreadable, orecur = self._safe_repr(o, context, maxlevels, level)
                    append(orepr)
                    if not oreadable:
                        readable = False
                    if orecur:
                        recursive = True
                del context[objid]
                return format % ", ".join(components), readable, recursive
    
            rep = repr(object)
            return rep, (rep and not rep.startswith('<')), False
    
    
    def pprint2(object, stream=None, indent=1, width=80, depth=None, *,
               compact=False):
        """Pretty-print a Python object to a stream [default is sys.stdout].
    
        dict items are left unsorted.
        """
        printer = UnsortedPrettyPrinter(
            stream=stream,
            indent=indent,
            width=width,
            depth=depth,
            compact=compact,
        )
        printer.pprint(object)
    
    
    def pformat2(object, indent=1, width=80, depth=None, *, compact=False):
        """Format a Python object into a pretty-printed representation.
    
        dict items are left unsorted.
        """
        return UnsortedPrettyPrinter(
            indent=indent,
            width=width,
            depth=depth,
            compact=compact,
        ).pformat(object)
    

提交回复
热议问题