pprint — Datenstrukturen ansprechend ausgeben¶
Quellcode: Lib/pprint.py
Das Modul pprint bietet die Möglichkeit, beliebige Python-Datenstrukturen ansprechend ausgegeben zu lassen, und zwar in einer Form, die sich wieder als Eingabe für den Interpreter verwenden lässt. Enthalten die formatierten Strukturen Objekte, die keine grundlegenden Python-Typen sind, lässt sich die Darstellung unter Umständen nicht mehr laden. Das kann bei Dateien, Sockets oder Klassen der Fall sein, ebenso bei vielen anderen Objekten, die sich nicht als Python-Literale darstellen lassen.
Die formatierte Darstellung hält Objekte auf einer einzigen Zeile, sofern das möglich ist, und bricht sie auf mehrere Zeilen um, wenn sie nicht in die erlaubte Breite passen. Diese lässt sich über den Parameter width einstellen und beträgt voreingestellt 80 Zeichen.
Geändert in Version 3.9: Unterstützung für die ansprechende Ausgabe von types.SimpleNamespace hinzugefügt.
Geändert in Version 3.10: Unterstützung für die ansprechende Ausgabe von dataclasses.dataclass hinzugefügt.
Funktionen¶
- pprint.pp(object, stream=None, indent=1, width=80, depth=None, *, compact=False, expand=False, sort_dicts=False, underscore_numbers=False)¶
Gibt die formatierte Darstellung von object aus, gefolgt von einem Zeilenumbruch. Diese Funktion lässt sich im interaktiven Interpreter anstelle der Funktion
print()verwenden, um Werte anzusehen. Tipp: Innerhalb eines Geltungsbereichs kannst duprint = pprint.ppzuweisen.- Parameter:
object – Das auszugebende Objekt.
stream (file-like object | None) – Ein dateiähnliches Objekt, in das die Ausgabe durch Aufruf seiner Methode
write()geschrieben wird. BeiNone(der Voreinstellung) wirdsys.stdoutverwendet.indent (int) – Der Einzug, der je Verschachtelungsebene hinzukommt.
width (int) – Die gewünschte Höchstzahl an Zeichen je Ausgabezeile. Lässt sich eine Struktur nicht innerhalb dieser Breite formatieren, wird das bestmögliche Ergebnis angestrebt.
depth (int | None) – Die Anzahl der Verschachtelungsebenen, die ausgegeben werden dürfen. Ist die auszugebende Datenstruktur zu tief, wird die nächste enthaltene Ebene durch
...ersetzt. BeiNone(der Voreinstellung) gibt es keine Beschränkung der Tiefe der formatierten Objekte.compact (bool) – Steuert, wie lange Sequenzen formatiert werden. Bei
False(der Voreinstellung) wird jedes Element einer Sequenz in eine eigene Zeile formatiert, andernfalls so viele Elemente je Ausgabezeile, wie in die width passen. Nicht mit expand vereinbar.expand (bool) – Bei
Truefolgt auf öffnende runde und eckige Klammern ein Zeilenumbruch und der nachfolgende Inhalt wird um eine Ebene eingerückt, ähnlich wie bei ansprechend ausgegebenem JSON. Nicht mit compact vereinbar.sort_dicts (bool) – Bei
Truewerden Dictionarys mit sortierten Schlüsseln formatiert, andernfalls in der Reihenfolge des Einfügens (die Voreinstellung).underscore_numbers (bool) – Bei
Truewerden ganze Zahlen mit dem Zeichen_als Tausendertrennzeichen formatiert, andernfalls werden keine Unterstriche angezeigt (die Voreinstellung).
>>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff) >>> pprint.pp(stuff) [<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']
Added in version 3.8.
Geändert in Version 3.10: Der Parameter underscore_numbers kam hinzu.
Geändert in Version 3.11: Es wird nicht mehr versucht, nach
sys.stdoutzu schreiben, wenn diesesNoneist.Geändert in Version 3.15: Der Parameter expand kam hinzu.
- pprint.pprint(object, stream=None, indent=1, width=80, depth=None, *, compact=False, expand=False, sort_dicts=True, underscore_numbers=False)¶
Alias für
pp(), bei dem sort_dicts voreingestellt aufTruesteht und die Schlüssel der Dictionarys damit selbsttätig sortiert werden. Meist ist stattdessenpp()die bessere Wahl, dort steht der Wert voreingestellt aufFalse.
- pprint.pformat(object, indent=1, width=80, depth=None, *, compact=False, expand=False, sort_dicts=True, underscore_numbers=False)¶
Gibt die formatierte Darstellung von object als Zeichenkette zurück. indent, width, depth, compact, expand, sort_dicts und underscore_numbers werden als Formatierungsparameter an den Konstruktor von
PrettyPrinterübergeben. Ihre Bedeutung ist oben beschrieben.
- pprint.isreadable(object)¶
Ermittelt, ob die formatierte Darstellung von object „lesbar“ ist, sich also mit
eval()wieder in den Wert zurückverwandeln lässt. Für rekursive Objekte wird stetsFalsezurückgegeben.>>> pprint.isreadable(stuff) False
- pprint.isrecursive(object)¶
Ermittelt, ob object eine rekursive Darstellung erfordert. Für diese Funktion gelten dieselben Einschränkungen wie unten bei
saferepr()beschrieben. Sie kannRecursionErrorauslösen, wenn sie ein rekursives Objekt nicht erkennt.
- pprint.saferepr(object)¶
Gibt eine Zeichenkettendarstellung von object zurück, geschützt gegen Rekursion in einigen verbreiteten Datenstrukturen, nämlich Instanzen von
dict,listundtuplesowie Unterklassen, deren__repr__nicht überschrieben wurde. Legt die Darstellung des Objekts einen rekursiven Eintrag offen, wird der rekursive Verweis als<Recursion on typename with id=number>dargestellt. Darüber hinaus wird die Darstellung nicht formatiert.>>> pprint.saferepr(stuff) "[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"
PrettyPrinter-Objekte¶
- class pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, compact=False, expand=False, sort_dicts=True, underscore_numbers=False)¶
Erzeugt eine
PrettyPrinter-Instanz.Die Argumente haben dieselbe Bedeutung wie bei
pp(). Beachte, dass sie in einer anderen Reihenfolge stehen und dass sort_dicts voreingestelltTrueist.>>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff[:]) >>> pp = pprint.PrettyPrinter(indent=4) >>> pp.pprint(stuff) [ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'], 'spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> pp = pprint.PrettyPrinter(width=41, compact=True) >>> pp.pprint(stuff) [['spam', 'eggs', 'lumberjack', 'knights', 'ni'], 'spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> pp = pprint.PrettyPrinter(width=41, expand=True, indent=3) >>> pp.pprint(stuff) [ [ 'spam', 'eggs', 'lumberjack', 'knights', 'ni', ], 'spam', 'eggs', 'lumberjack', 'knights', 'ni', ] >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', ... ('parrot', ('fresh fruit',)))))))) >>> pp = pprint.PrettyPrinter(depth=6) >>> pp.pprint(tup) ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
Geändert in Version 3.4: Der Parameter compact kam hinzu.
Geändert in Version 3.8: Der Parameter sort_dicts kam hinzu.
Geändert in Version 3.10: Der Parameter underscore_numbers kam hinzu.
Geändert in Version 3.11: Es wird nicht mehr versucht, nach
sys.stdoutzu schreiben, wenn diesesNoneist.Geändert in Version 3.15: Der Parameter expand kam hinzu.
PrettyPrinter-Instanzen haben die folgenden Methoden:
- PrettyPrinter.pformat(object)¶
Gibt die formatierte Darstellung von object zurück. Dabei werden die Optionen berücksichtigt, die dem Konstruktor von
PrettyPrinterübergeben wurden.
- PrettyPrinter.pprint(object)¶
Gibt die formatierte Darstellung von object auf dem eingestellten Strom aus, gefolgt von einem Zeilenumbruch.
Die folgenden Methoden stellen die Umsetzung der entsprechenden gleichnamigen Funktionen bereit. Diese Methoden an einer Instanz zu verwenden ist etwas effizienter, da keine neuen PrettyPrinter-Objekte erzeugt werden müssen.
- PrettyPrinter.isreadable(object)¶
Ermittelt, ob die formatierte Darstellung des Objekts „lesbar“ ist, sich also mit
eval()wieder in den Wert zurückverwandeln lässt. Beachte, dass für rekursive ObjekteFalsezurückgegeben wird. Ist der Parameter depth desPrettyPrintergesetzt und das Objekt tiefer als erlaubt, wird ebenfallsFalsezurückgegeben.
- PrettyPrinter.isrecursive(object)¶
Ermittelt, ob das Objekt eine rekursive Darstellung erfordert.
Diese Methode ist als Einhängepunkt gedacht, damit Unterklassen ändern können, wie Objekte in Zeichenketten umgewandelt werden. Die voreingestellte Umsetzung verwendet das Innenleben der Umsetzung von saferepr().
- PrettyPrinter.format(object, context, maxlevels, level)¶
Gibt drei Werte zurück: die formatierte Fassung von object als Zeichenkette, ein Kennzeichen dafür, ob das Ergebnis lesbar ist, und ein Kennzeichen dafür, ob Rekursion erkannt wurde. Das erste Argument ist das darzustellende Objekt. Das zweite ist ein Dictionary, dessen Schlüssel die
id()jener Objekte sind, die zum aktuellen Darstellungskontext gehören (direkte und indirekte Behälter von object, die die Darstellung beeinflussen). Muss ein Objekt dargestellt werden, das in context schon vertreten ist, sollte der dritte RückgabewertTruesein. Rekursive Aufrufe der Methodeformat()sollten diesem Dictionary weitere Einträge für Behälter hinzufügen. Das dritte Argument, maxlevels, gibt die gewünschte Grenze für die Rekursion an. Es ist0, wenn keine Grenze gewünscht ist. Dieses Argument sollte unverändert an rekursive Aufrufe weitergegeben werden. Das vierte Argument, level, gibt die aktuelle Ebene an. Rekursiven Aufrufen sollte ein Wert übergeben werden, der kleiner als der des aktuellen Aufrufs ist.
Beispiel¶
Um mehrere Verwendungen der Funktion pp() und ihrer Parameter zu zeigen, holen wir Informationen über ein Projekt von PyPI ab:
>>> import json
>>> import pprint
>>> from urllib.request import urlopen
>>> with urlopen('https://pypi.org/pypi/sampleproject/1.2.0/json') as resp:
... project_info = json.load(resp)['info']
In seiner Grundform zeigt pp() das gesamte Objekt:
>>> pprint.pp(project_info)
{'author': 'The Python Packaging Authority',
'author_email': 'pypa-dev@googlegroups.com',
'bugtrack_url': None,
'classifiers': ['Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Topic :: Software Development :: Build Tools'],
'description': 'A sample Python project\n'
'=======================\n'
'\n'
'This is the description file for the project.\n'
'\n'
'The file should use UTF-8 encoding and be written using '
'ReStructured Text. It\n'
'will be used to generate the project webpage on PyPI, and '
'should be written for\n'
'that purpose.\n'
'\n'
'Typical contents for this file would include an overview of '
'the project, basic\n'
'usage examples, etc. Generally, including the project '
'changelog in here is not\n'
'a good idea, although a simple "What\'s New" section for the '
'most recent version\n'
'may be appropriate.',
'description_content_type': None,
'docs_url': None,
'download_url': 'UNKNOWN',
'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
'home_page': 'https://github.com/pypa/sampleproject',
'keywords': 'sample setuptools development',
'license': 'MIT',
'maintainer': None,
'maintainer_email': None,
'name': 'sampleproject',
'package_url': 'https://pypi.org/project/sampleproject/',
'platform': 'UNKNOWN',
'project_url': 'https://pypi.org/project/sampleproject/',
'project_urls': {'Download': 'UNKNOWN',
'Homepage': 'https://github.com/pypa/sampleproject'},
'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
'requires_dist': None,
'requires_python': None,
'summary': 'A sample Python project',
'version': '1.2.0'}
Das Ergebnis lässt sich auf eine bestimmte depth begrenzen. Für tiefere Inhalte stehen dann Auslassungspunkte:
>>> pprint.pp(project_info, depth=1)
{'author': 'The Python Packaging Authority',
'author_email': 'pypa-dev@googlegroups.com',
'bugtrack_url': None,
'classifiers': [...],
'description': 'A sample Python project\n'
'=======================\n'
'\n'
'This is the description file for the project.\n'
'\n'
'The file should use UTF-8 encoding and be written using '
'ReStructured Text. It\n'
'will be used to generate the project webpage on PyPI, and '
'should be written for\n'
'that purpose.\n'
'\n'
'Typical contents for this file would include an overview of '
'the project, basic\n'
'usage examples, etc. Generally, including the project '
'changelog in here is not\n'
'a good idea, although a simple "What\'s New" section for the '
'most recent version\n'
'may be appropriate.',
'description_content_type': None,
'docs_url': None,
'download_url': 'UNKNOWN',
'downloads': {...},
'home_page': 'https://github.com/pypa/sampleproject',
'keywords': 'sample setuptools development',
'license': 'MIT',
'maintainer': None,
'maintainer_email': None,
'name': 'sampleproject',
'package_url': 'https://pypi.org/project/sampleproject/',
'platform': 'UNKNOWN',
'project_url': 'https://pypi.org/project/sampleproject/',
'project_urls': {...},
'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
'requires_dist': None,
'requires_python': None,
'summary': 'A sample Python project',
'version': '1.2.0'}
Außerdem lässt sich eine größte Zeichenbreite width vorschlagen. Kann ein langes Objekt nicht umgebrochen werden, wird die angegebene Breite überschritten:
>>> pprint.pp(project_info, depth=1, width=60)
{'author': 'The Python Packaging Authority',
'author_email': 'pypa-dev@googlegroups.com',
'bugtrack_url': None,
'classifiers': [...],
'description': 'A sample Python project\n'
'=======================\n'
'\n'
'This is the description file for the '
'project.\n'
'\n'
'The file should use UTF-8 encoding and be '
'written using ReStructured Text. It\n'
'will be used to generate the project '
'webpage on PyPI, and should be written '
'for\n'
'that purpose.\n'
'\n'
'Typical contents for this file would '
'include an overview of the project, '
'basic\n'
'usage examples, etc. Generally, including '
'the project changelog in here is not\n'
'a good idea, although a simple "What\'s '
'New" section for the most recent version\n'
'may be appropriate.',
'description_content_type': None,
'docs_url': None,
'download_url': 'UNKNOWN',
'downloads': {...},
'home_page': 'https://github.com/pypa/sampleproject',
'keywords': 'sample setuptools development',
'license': 'MIT',
'maintainer': None,
'maintainer_email': None,
'name': 'sampleproject',
'package_url': 'https://pypi.org/project/sampleproject/',
'platform': 'UNKNOWN',
'project_url': 'https://pypi.org/project/sampleproject/',
'project_urls': {...},
'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
'requires_dist': None,
'requires_python': None,
'summary': 'A sample Python project',
'version': '1.2.0'}
Zuletzt lässt sich mit dem Parameter expand wie bei ansprechend ausgegebenem JSON formatieren. Die besten Ergebnisse erzielt ein höherer Wert für indent:
>>> pprint.pp(project_info, indent=4, expand=True)
{
'author': 'The Python Packaging Authority',
'author_email': 'pypa-dev@googlegroups.com',
'bugtrack_url': None,
'classifiers': [
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Topic :: Software Development :: Build Tools',
],
'description': 'A sample Python project\n'
'=======================\n'
'\n'
'This is the description file for the project.\n'
'\n'
'The file should use UTF-8 encoding and be written using ReStructured '
'Text. It\n'
'will be used to generate the project webpage on PyPI, and should be '
'written for\n'
'that purpose.\n'
'\n'
'Typical contents for this file would include an overview of the project, '
'basic\n'
'usage examples, etc. Generally, including the project changelog in here '
'is not\n'
'a good idea, although a simple "What\'s New" section for the most recent '
'version\n'
'may be appropriate.',
'description_content_type': None,
'docs_url': None,
'download_url': 'UNKNOWN',
'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
'dynamic': None,
'home_page': 'https://github.com/pypa/sampleproject',
'keywords': 'sample setuptools development',
'license': 'MIT',
'license_expression': None,
'license_files': None,
'maintainer': None,
'maintainer_email': None,
'name': 'sampleproject',
'package_url': 'https://pypi.org/project/sampleproject/',
'platform': 'UNKNOWN',
'project_url': 'https://pypi.org/project/sampleproject/',
'project_urls': {
'Download': 'UNKNOWN',
'Homepage': 'https://github.com/pypa/sampleproject',
},
'provides_extra': None,
'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
'requires_dist': None,
'requires_python': None,
'summary': 'A sample Python project',
'version': '1.2.0',
'yanked': False,
'yanked_reason': None,
}