pprint – データ構造を見やすい形で出力する¶
目的: | データ構造を見やすい形で出力する |
---|---|
利用できるバージョン: | 1.4 |
pprint はデータ構造の表現を見て美しい形で出力する “pretty printer” を提供します。そのフォーマッタはインタープリタが正しく解析したデータ構造の形を生成します。さらにそれは人間にとっても読み易いです。その出力はできるだけ1行でなされ、複数行にわたるときはインデントされます。
全てのサンプルは pprint_data.py に依存しており、そのファイルは次のデータを含んでいます。
data = [ (i, { 'a':'A',
'b':'B',
'c':'C',
'd':'D',
'e':'E',
'f':'F',
'g':'G',
'h':'H',
})
for i in xrange(3)
]
表示¶
このモジュールを使う一番シンプルな方法は pprint() 関数を使うことです。この関数は引数として渡されたオブジェクトを整形して、その内容をデータストリーム(デフォルトでは sys.stdout)へ書き込みます。
from pprint import pprint
from pprint_data import data
print 'PRINT:'
print data
print
print 'PPRINT:'
pprint(data)
$ python pprint_pprint.py
PRINT:
[(0, {'a': 'A', 'c': 'C', 'b': 'B', 'e': 'E', 'd': 'D', 'g': 'G', 'f': 'F', 'h': 'H'}), (1, {'a': 'A', 'c': 'C', 'b': 'B', 'e': 'E', 'd': 'D', 'g': 'G', 'f': 'F', 'h': 'H'}), (2, {'a': 'A', 'c': 'C', 'b': 'B', 'e': 'E', 'd': 'D', 'g': 'G', 'f': 'F', 'h': 'H'})]
PPRINT:
[(0,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'}),
(1,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'}),
(2,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'})]
体裁を整える¶
データ構造の体裁を整える必要があるが、直接ストリームに書き出したくない場合(例えば、ログ目的)、別の関数へ渡せるようにそのデータ構造の文字列表現を組み立てる pformat() を使うことができます。
import logging
from pprint import pformat
from pprint_data import data
logging.basicConfig(level=logging.DEBUG,
format='%(levelname)-8s %(message)s',
)
logging.debug('Logging pformatted data')
logging.debug(pformat(data))
$ python pprint_pformat.py
DEBUG Logging pformatted data
DEBUG [(0,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'}),
(1,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'}),
(2,
{'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H'})]
任意のクラス¶
pprint() が使う PrettyPrinter クラスは __repr__() メソッドを定義すれば、独自のクラスと連携することもできます。
from pprint import pprint
class node(object):
def __init__(self, name, contents=[]):
self.name = name
self.contents = contents[:]
def __repr__(self):
return 'node(' + repr(self.name) + ', ' + repr(self.contents) + ')'
trees = [ node('node-1'),
node('node-2', [ node('node-2-1')]),
node('node-3', [ node('node-3-1')]),
]
pprint(trees)
$ python pprint_arbitrary_object.py
[node('node-1', []),
node('node-2', [node('node-2-1', [])]),
node('node-3', [node('node-3-1', [])])]
再帰型のデータ¶
再帰的なデータ構造は <Recursion on typename with id=number> という形式でデータの元のソースへの参照として表現されます。例えば
from pprint import pprint
local_data = [ 'a', 'b', 1, 2 ]
local_data.append(local_data)
print 'id(local_data) =>', id(local_data)
pprint(local_data)
$ python pprint_recursion.py
id(local_data) => 4299545416
['a', 'b', 1, 2, <Recursion on list with id=4299545416>]
入れ子になった出力の制限¶
とても深い構造を持ったデータに対しては、全ての詳細を出力に含めたくないかもしれません。適切にデータの体裁を整えるのは不可能かもしれないし、体裁を整えた後のテキストデータは管理するには大きすぎるかもしれません。もしくは全ての詳細が必要かもしれません。そういった場合、pretty printer が入れ子になったデータ構造をどのぐらい辿るのかを depth 引数で制御することができます。
from pprint import pprint
from pprint_data import data
pprint(data, depth=1)
$ python pprint_depth.py
[(...), (...), (...)]
出力の幅の設定¶
体裁を整えたテキストのデフォルト幅は 80 列です。その幅を調整するには pprint() の width 引数を使用してください。
from pprint import pprint
from pprint_data import data
for d in data:
for c in 'defgh':
del d[1][c]
for width in [ 80, 20, 5 ]:
print 'WIDTH =', width
pprint(data, width=width)
print
体裁を整えたデータ構造を表示するのにその幅が狭すぎるとき、そのデータ構造が不正な構文であっても、その行が切り捨てられたり、まとめられたりはしないことに注意してください。
$ python pprint_width.py
WIDTH = 80
[(0, {'a': 'A', 'b': 'B', 'c': 'C'}),
(1, {'a': 'A', 'b': 'B', 'c': 'C'}),
(2, {'a': 'A', 'b': 'B', 'c': 'C'})]
WIDTH = 20
[(0,
{'a': 'A',
'b': 'B',
'c': 'C'}),
(1,
{'a': 'A',
'b': 'B',
'c': 'C'}),
(2,
{'a': 'A',
'b': 'B',
'c': 'C'})]
WIDTH = 5
[(0,
{'a': 'A',
'b': 'B',
'c': 'C'}),
(1,
{'a': 'A',
'b': 'B',
'c': 'C'}),
(2,
{'a': 'A',
'b': 'B',
'c': 'C'})]
See also
- pprint
- 本モジュールの標準ライブラリドキュメント