MENU

Pythonツールの標準出力とエラー出力を分ける

当ページのリンクには広告(PR)が含まれていることがあります。
Pythonツールの標準出力とエラー出力を分ける。結果と診断文、出力先を分ける、結果へ混ぜないの処理例。

集計結果のJSONへ「処理を開始しました」という一行が混ざると、次の道具で読めなくなります。人に見せる説明と、機械へ渡す結果を同じprintで出している場合に起こる問題です。

Pythonの標準出力stdoutと標準エラー出力stderrは分けて使えます。stdoutには決めた形式の結果、stderrには診断を出すと、次の処理へ結果を渡しやすくなります。

目次

結果を一件のJSONとして返す

次は引数の整数を足す小さな例です。引数を省略すると架空の10と20を使います。整数へ変換できない場合はstderrへ理由を出し、終了コード2で終わります。

import json
import sys

def main():
    inputs = sys.argv[1:] or ["10", "20"]
    try:
        values = [int(value) for value in inputs]
    except ValueError:
        print("整数にできない入力があります", file=sys.stderr)
        return 2
    result = {"count": len(values), "total": sum(values)}
    print(json.dumps(result, ensure_ascii=False))
    print(f"処理件数: {len(values)}", file=sys.stderr)
    return 0

if __name__ == "__main__":
    raise SystemExit(main())

引数なしのstdoutは、countが2、totalが30のJSON一件です。stderrには処理件数が出ます。端末では二つの出力が続けて見える場合がありますが、別の出力先です。

Windows・Python 3.12.10で、出力を分けて受け取る形で確認しました。badを引数にした場合は終了コード2でstdoutが空になること、0と5なら合計5のJSONになることも確認しています。

診断が出たことと失敗を分ける

stderrという名前でも、正常時の進捗や確認用の情報を出せます。この例は成功時にも処理件数をstderrへ書いています。stderrに文字があったという理由だけで、ジョブを失敗と判定する設計にはしません。

成否は終了コード、結果の形式、必要な出力の確認を合わせます。0以外の具体的な意味はツールごとに定義し、READMEへ残します。エラーを表示しても0で終了する構成では、呼び出し側が失敗に気づけない場合があります。

結果の前後に説明を足さない

stdoutを機械向けに決めたら、デバッグ用のprintも混ぜないようにします。成功の一言や区切り線だけでも、JSONとして読む後段では余計な文字になります。

利用者向けの詳しい案内を出すモードが必要なら、機械用の出力モードと分ける方法があります。必要な結果の形式を決めず、受け取る側で先頭や末尾の説明を削る対応を重ねると、変更に弱くなります。

保存先の文字コードも確認する

シェルでファイルへ出力する場合は、保存方法やシェルのバージョンによって文字コードが変わることがあります。Pythonの出力が分かれたことだけで、保存したファイルを後段が同じ文字コードで読めるとは判断しません。

実際に使う起動方法でstdoutとstderrを別々に保存し、結果をJSONとして読み直してください。ログへ入力の全文や秘密を出す必要があるかも分けて判断します。この例は架空の整数と件数だけを表示しています。

引数の設計はargparse入門、継続して残す診断はlogging入門で補えます。

参考資料

Python sys公式資料を2026年11月1日に確認しました。

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次