pprint — 資料美化列印

原始碼: Lib/pprint.py


pprint 模組提供了一種以可作為直譯器輸入的形式“美化列印”任意 Python 資料結構的功能。如果格式化的結構包含的不是基本的 Python 型別,則該表示形式可能無法載入。如果包含檔案、套接字或類等物件,以及許多其他無法表示為 Python 字面量的物件,則可能會出現這種情況。

格式化表示形式會盡可能將物件放在同一行,如果物件不適合允許的寬度,則會將其拆分到多行,該寬度可透過 width 引數進行調整,預設為 80 個字元。

在計算顯示之前,字典會按鍵排序。

在 3.9 版本中更改: 增加了對美化列印 types.SimpleNamespace 的支援。

在 3.10 版本中更改: 增加了對美化列印 dataclasses.dataclass 的支援。

函式

pprint.pp(object, stream=None, indent=1, width=80, depth=None, *, compact=False, sort_dicts=False, underscore_numbers=False)

列印 object 的格式化表示形式,後跟一個換行符。此函式可以在互動式直譯器中代替 print() 函式用於檢查值。提示:您可以在作用域內重新分配 print = pprint.pp 以便使用。

引數:
  • object – 要列印的物件。

  • stream (類檔案物件 | None) – 一個類檔案物件,將透過呼叫其 write() 方法將輸出寫入到該物件。如果為 None(預設值),則使用 sys.stdout

  • indent (int) – 每個巢狀級別新增的縮排量。

  • width (int) – 輸出中每行所需的最多字元數。如果結構無法在寬度約束內格式化,則會盡最大努力進行格式化。

  • depth (int | None) – 可以列印的巢狀級別數。如果要列印的資料結構太深,則下一個包含的級別將被替換為 ...。如果為 None(預設值),則對格式化的物件的深度沒有約束。

  • compact (bool) – 控制格式化長 序列 的方式。如果為 False(預設值),則序列的每個專案將在單獨的行上格式化,否則,將在每行輸出上格式化儘可能多的專案,以便適應 width

  • sort_dicts (bool) – 如果為 True,則字典將按鍵排序格式化,否則將按插入順序顯示(預設值)。

  • underscore_numbers (bool) – 如果為 True,則整數將使用 _ 字元作為千位分隔符格式化,否則不顯示下劃線(預設值)。

>>> 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']

在 3.8 版本中新增。

pprint.pprint(object, stream=None, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

別名 pp(),其中 sort_dicts 預設設定為 True,這將自動對字典的鍵進行排序,您可能想要使用 pp(),其中預設值為 False

pprint.pformat(object, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

以字串形式返回 object 的格式化表示形式。indentwidthdepthcompactsort_dictsunderscore_numbers 作為格式化引數傳遞給 PrettyPrinter 建構函式,它們的含義如上述文件中所述。

pprint.isreadable(object)

確定 object 的格式化表示形式是否“可讀”,或者是否可以使用 eval() 重構該值。對於遞迴物件,此函式始終返回 False

>>> pprint.isreadable(stuff)
False
pprint.isrecursive(object)

確定 object 是否需要遞迴表示。此函式受到與下面 saferepr() 中所述相同的限制,如果無法檢測到遞迴物件,可能會引發 RecursionError

pprint.saferepr(object)

返回 object 的字串表示形式,該表示形式針對一些常見資料結構(即 dictlisttuple 的例項或其 __repr__ 未被覆蓋的子類)中的遞迴進行了保護。如果 object 的表示形式暴露了遞迴條目,則遞迴引用將表示為 <Recursion on typename with id=number>。該表示形式沒有進行其他格式化。

>>> pprint.saferepr(stuff)
"[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"

PrettyPrinter 物件

class pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

構造一個 PrettyPrinter 例項。

引數的含義與 pp() 的含義相同。請注意,它們的順序不同,並且 sort_dicts 預設為 True

>>> 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']
>>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
... ('parrot', ('fresh fruit',))))))))
>>> pp = pprint.PrettyPrinter(depth=6)
>>> pp.pprint(tup)
('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))

在 3.4 版本中更改: 添加了 compact 引數。

在 3.8 版本中更改: 添加了 sort_dicts 引數。

在 3.10 版本中更改: 添加了 underscore_numbers 引數。

在 3.11 版本中更改: 如果 sys.stdoutNone,則不再嘗試寫入它。

PrettyPrinter 例項具有以下方法

PrettyPrinter.pformat(object)

返回 object 的格式化表示形式。這會考慮傳遞給 PrettyPrinter 建構函式的選項。

PrettyPrinter.pprint(object)

在配置的流上列印 object 的格式化表示形式,後跟換行符。

以下方法提供了同名對應函式的實現。在例項上使用這些方法效率稍高,因為不需要建立新的 PrettyPrinter 物件。

PrettyPrinter.isreadable(object)

確定物件的格式化表示形式是否“可讀”,或者是否可以使用 eval() 重構該值。請注意,對於遞迴物件,這將返回 False。如果設定了 PrettyPrinterdepth 引數,並且物件比允許的深度更深,則這將返回 False

PrettyPrinter.isrecursive(object)

確定物件是否需要遞迴表示。

提供此方法作為鉤子,以允許子類修改物件轉換為字串的方式。預設實現使用 saferepr() 實現的內部結構。

PrettyPrinter.format(object, context, maxlevels, level)

返回三個值:object 的格式化版本(字串)、一個指示結果是否可讀的標誌以及一個指示是否檢測到遞迴的標誌。第一個引數是要呈現的物件。第二個引數是一個字典,其中包含作為鍵的當前呈現上下文(影響呈現的 object 的直接和間接容器)的一部分的物件的 id();如果需要呈現的物件已在 context 中表示,則第三個返回值應為 True。對 format() 方法的遞迴呼叫應將容器的其他條目新增到此字典中。第三個引數 maxlevels 給出了請求的遞迴限制;如果沒有請求的限制,則此引數將為 0。此引數應不做修改地傳遞給遞迴呼叫。第四個引數 level 給出了當前級別;遞迴呼叫應傳遞一個小於當前呼叫的值。

示例

為了演示 pp() 函式及其引數的幾種用法,讓我們從 PyPI 獲取有關專案的資訊

>>> 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']

在其基本形式中,pp() 顯示整個物件

>>> 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'}

結果可以限制為某個 depth (省略號用於更深的內容)

>>> 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'}

此外,可以建議最大字元 width。如果無法拆分長物件,則將超過指定的寬度

>>> 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'}