
Python Tips: print() の代わりに rich.print() を使おう
こんにちは、けんにぃです。ナビタイムジャパンで公共交通の時刻表を使ったサービス開発やリリースフローの改善を担当しています。
今回は Python でコマンドラインツールを作るときに役立つライブラリとして Rich というものをご紹介したいと思います。
Rich とは
Rich はターミナルに出力するメッセージを簡単に整形したり色付けしたりすることができる pretty-print ライブラリです。
コマンドラインツールを作るときに色や書体が配慮されていると、情報にメリハリが付いて視認性が向上するので、ぜひオススメしたいライブラリとなっています。
インストール
まずは Rich をインストールします。
$ pip install rich
機能ごとに簡単な使い方を紹介していきます。
まずはメッセージ出力です。
#!/usr/bin/env python
from rich import print
print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", locals())

とてもカラフルですね。辞書が整形されて色付きで出力されていますが、Python のオブジェクトは rich.print() が自動で pretty-print してくれます。
テキストを色付けしたり書体を変えたりしたい場合は BBCode というマークアップ言語の形式で記述します。
例:
・[bold]太字[/bold]
・[red]赤色[/red]
・[u]下線[/u]
・[i]斜体[/i]
なお閉じタグは [/] と書いても大丈夫なようです。rich.print() は標準の print() と互換性があるので、入れ替えるのは簡単です。
絵文字の出力も可能です。
#!/usr/bin/env python
from rich import print
print(":dog: :cat: :rabbit:")

Console
Console という機能を使ってもメッセージを出力できますが、print と違ってConsole はワードラップが有効になります。
#!/usr/bin/env python
from rich.console import Console
console = Console()
console.print("Hello, [bold red]World![/bold red]")
さらに console.log() という関数を使うとファイル名や行数なども含めたメッセージが出力できるようになります。
#!/usr/bin/env python
from rich.console import Console
console = Console()
def hello():
message1 = "Hello"
message2 = "World"
console.log(f"[red]{message1}[/], [cyan]{message2}![/]", log_locals=True)
hello()

console.log() に渡している log_locals という引数を True にすると、関数内で定義されたローカル変数を表形式で出力してくれます。
console.log() と同じ書式を Python 標準の logging モジュールでも使いたい場合は下記のようにします。
#!/usr/bin/env python
import logging
from rich.logging import RichHandler
logging.basicConfig(
level="NOTSET",
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler()],
)
logger = logging.getLogger("main")
logger.info("Hello, World!")

表の出力
Table を使うと表を出力することができます。下記のコードは virtualenv 内にあるディレクトリ .venv/lib/python3.6/site-packages 配下のファイルの一覧を表示するプログラムです。
#!/usr/bin/env python
from pathlib import Path
from rich.console import Console
from rich.table import Table
console = Console()
table = Table(show_header=True, header_style="bold magenta")
table.add_column("Name")
table.add_column("Attribute")
for path in Path(".venv/lib/python3.6/site-packages").glob("*"):
attr = "File" if path.is_file() else "Directory"
table.add_row(path.stem, attr)
console.print(table)

進捗バー
progress は進捗バーを出力するための機能です。
#!/usr/bin/env python
import time
from rich.progress import track
for _ in track(range(100)):
time.sleep(0.1)

コードハイライト
Syntax を使うとコードハイライトができるようになります。
#!/usr/bin/env python
from rich import print
from rich.syntax import Syntax
with open("main.py") as f:
print(Syntax(f.read(), "python"))

Markdown も同様に色付けができますが Markdown という専用のクラスを使えば特別な装飾をしてくれます。
#!/usr/bin/env python
from rich import print
from rich.markdown import Markdown
with open("README.md") as f:
print(Markdown(f.read()))
コード内で読み込んでいる README.md が下記のような内容だとすると……
# Rich の導入
## インストール
```
$ pip install rich
```
## 使い方
```python
#!/usr/bin/env python
from rich import print
print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", locals())
```
実行結果は次のようになります。

バックトレース
例外が送出されたときに出てくるバックトレースもカラフルにできます。
#!/usr/bin/env python
from rich.traceback import install
install()
x = 10 / 0
print(x)

さいごに
Rich の簡単な使い方をご紹介しました。ぜひコマンドラインツールの開発で活用してみてください。