pprint --- 數(shù)據(jù)美化輸出?

源代碼: Lib/pprint.py


pprint 模塊提供了“美化打印”任意 Python 數(shù)據(jù)結(jié)構(gòu)的功能,這種美化形式可用作對(duì)解釋器的輸入。 如果經(jīng)格式化的結(jié)構(gòu)包含非基本 Python 類型的對(duì)象,則其美化形式可能無法被加載。 包含文件、套接字或類對(duì)象,以及許多其他不能用 Python 字面值來表示的對(duì)象都有可能導(dǎo)致這樣的結(jié)果。

格式化后的形式會(huì)在可能的情況下以單行來表示對(duì)象,并在無法在允許寬度內(nèi)容納對(duì)象的情況下將其分為多行。 如果你需要調(diào)整寬度限制則應(yīng)顯式地構(gòu)造 PrettyPrinter 對(duì)象。

Dictionaries are sorted by key before the display is computed. 字典在被計(jì)算前通過鍵值來排序。

pprint 模塊定義了一個(gè)類:

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

構(gòu)造一個(gè) PrettyPrinter 實(shí)例。 此構(gòu)造器接受幾個(gè)關(guān)鍵字形參。 使用 stream 關(guān)鍵字可設(shè)置輸出流;在流對(duì)象上使用的唯一方法是文件協(xié)議的 write() 方法。 如果未指定此關(guān)鍵字,則 PrettyPrinter 會(huì)選擇 sys.stdout。 每個(gè)遞歸層級(jí)的縮進(jìn)量由 indent 指定;默認(rèn)值為一。 其他值可導(dǎo)致輸出看起來有些怪異,但可使得嵌套結(jié)構(gòu)更易區(qū)分。 可被打印的層級(jí)數(shù)量由 depth 控制;如果數(shù)據(jù)結(jié)構(gòu)的層級(jí)被打印得過深,其所包含的下一層級(jí)會(huì)被替換為 ...。 在默認(rèn)情況下,對(duì)被格式化對(duì)象的層級(jí)深度沒有限制。 希望的輸出寬度可使用 width 形參來限制;默認(rèn)值為 80 個(gè)字符。 如果一個(gè)結(jié)構(gòu)無法在限定寬度內(nèi)被格式化,則將做到盡可能接近。 如果 compact 為假值(默認(rèn))則長序列的每一項(xiàng)將被格式化為單獨(dú)的行。 如果 compact 為真值,則格式化將在 width 可容納的情況下把盡可能多的項(xiàng)放入每個(gè)輸出行。

在 3.4 版更改: 加入*compact* 參數(shù)。

>>> 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', (...)))))))

pprint 模塊還提供了一些快捷函數(shù):

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

object 格式化表示作為字符串返回。 indent, width, depthcompact 將作為格式化形參被傳入 PrettyPrinter 構(gòu)造器。

在 3.4 版更改: 加入*compact* 參數(shù)。

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

stream 上打印 object 的格式化表示,并附帶一個(gè)換行符。 如果 streamNone,則使用 sys.stdout。 這可以替換 print() 函數(shù)在交互式解釋器中使用以查看值(你甚至可以執(zhí)行重新賦值 print = pprint.pprint 以在特定作用域中使用)。 indent, width, depthcompact 將作為格式化形參被傳給 PrettyPrinter 構(gòu)造器。

在 3.4 版更改: 加入*compact* 參數(shù)。

>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff)
>>> pprint.pprint(stuff)
[<Recursion on list with id=...>,
 'spam',
 'eggs',
 'lumberjack',
 'knights',
 'ni']
pprint.isreadable(object)?

確定 object 的格式化表示是否“可讀”,或是否可被用來通過 eval() 重新構(gòu)建對(duì)象的值。 此函數(shù)對(duì)于遞歸對(duì)象總是返回 False

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

確定 object 是否需要遞歸表示。

此外還定義了一個(gè)支持函數(shù):

pprint.saferepr(object)?

返回 object 的字符串表示,并為遞歸數(shù)據(jù)結(jié)構(gòu)提供保護(hù)。 如果 object 的表示形式公開了一個(gè)遞歸條目,該遞歸引用會(huì)被表示為 <Recursion on typename with id=number>。 該表示因而不會(huì)進(jìn)行其它格式化。

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

PrettyPrinter 對(duì)象?

PrettyPrinter 的實(shí)例具有下列方法:

PrettyPrinter.pformat(object)?

返回 object 格式化表示。 這會(huì)將傳給 PrettyPrinter 構(gòu)造器的選項(xiàng)納入考慮。

PrettyPrinter.pprint(object)?

在所配置的流上打印 object 的格式化表示,并附加一個(gè)換行符。

下列方法提供了與同名函數(shù)相對(duì)應(yīng)的實(shí)現(xiàn)。 在實(shí)例上使用這些方法效率會(huì)更高一些,因?yàn)椴恍枰獎(jiǎng)?chuàng)建新的 PrettyPrinter 對(duì)象。

PrettyPrinter.isreadable(object)?

確定對(duì)象的格式化表示是否“可讀”,或者是否可使用 eval() 重建對(duì)象值。 請(qǐng)注意此方法對(duì)于遞歸對(duì)象將返回 False。 如果設(shè)置了 PrettyPrinterdepth 形參并且對(duì)象深度超出允許范圍,此方法將返回 False。

PrettyPrinter.isrecursive(object)?

確定對(duì)象是否需要遞歸表示。

此方法作為一個(gè)鉤子提供,允許子類修改將對(duì)象轉(zhuǎn)換為字符串的方式。 默認(rèn)實(shí)現(xiàn)使用 saferepr() 實(shí)現(xiàn)的內(nèi)部方式。

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

返回三個(gè)值:字符串形式的 object 已格式化版本,指明結(jié)果是否可讀的旗標(biāo),以及指明是否檢測到遞歸的旗標(biāo)。 第一個(gè)參數(shù)是要表示的對(duì)象。 第二個(gè)是以對(duì)象 id() 為鍵的字典,這些對(duì)象是當(dāng)前表示上下文的一部分(影響 object 表示的直接和間接容器);如果需要呈現(xiàn)一個(gè)已經(jīng)在 context 中表示的對(duì)象,則第三個(gè)返回值應(yīng)當(dāng)為 True。 對(duì) format() 方法的遞歸調(diào)用應(yīng)當(dāng)將容器的附加條目添加到此字典中。 第三個(gè)參數(shù) maxlevels 給出了對(duì)遞歸的請(qǐng)求限制;如果沒有請(qǐng)求限制則其值將為 0。 此參數(shù)應(yīng)當(dāng)不加修改地傳給遞歸調(diào)用。 第四個(gè)參數(shù) level 給出于當(dāng)前層級(jí);傳給遞歸調(diào)用的參數(shù)值應(yīng)當(dāng)小于當(dāng)前調(diào)用的值。

示例?

為了演示 pprint() 函數(shù)及其形參的幾種用法,讓我們從 PyPI 獲取關(guān)于某個(gè)項(xiàng)目的信息:

>>> import json
>>> import pprint
>>> from urllib.request import urlopen
>>> with urlopen('https://pypi.org/pypi/sampleproject/json') as resp:
...     project_info = json.load(resp)['info']

pprint() 以其基本形式顯示了整個(gè)對(duì)象:

>>> pprint.pprint(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'}

結(jié)果可以被限制到特定的 depth (更深層的內(nèi)容將使用省略號(hào)):

>>> pprint.pprint(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'}

此外,還可以設(shè)置建議的最大字符 width。 如果一個(gè)對(duì)象無法被拆分,則將超出指定寬度:

>>> pprint.pprint(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'}