HOWTO · Python

TypeError を解決する: Python での文字列の書式設定中にすべての引数が変換されるわけではありません

この記事では、Python で文字列を書式設定する際に発生する `TypeError: not all arguments converted during string formatting` の原因を説明します。`%` 書式設定では `%s` や `%d` などのプレースホルダーに値を対応させる必要があり、余分な値が残るとこのエラーが発生することがあります。また、波括弧のプレースホルダーは `%` 書式設定では値を消費しないため、たとえば `{}` を含むテンプレートに `%` で値を渡すと不一致が起きます。入力文字列を数値として扱う場合の変換方法や、書式設定方式の選び方も紹介します。

このページの内容

エラー TypeError: not all arguments converted during string formatting は通常、Python が % を旧式の文字列書式設定として扱い、文字列内の書式指定子で使われない値が残ったことを示します。同じ演算子は数値の剰余計算にも使われるため、オペランドの型と位置が重要です。% の左側が文字列なら、文字列書式設定が選ばれます。まずその演算を確認し、各プレースホルダーに対応する値があるかを確かめましょう。以下の例では、それぞれのケースを見分け、一貫した書式設定方法を選ぶ手順を説明します。

このTypeErrorが示すこと

数値に対する % は剰余を返します。左側が文字列の場合、% は旧式の書式設定を行います。たとえば %s や %d のようなプレースホルダーは、その文字列に埋め込む値を指定します。したがって、式の意味は右側の値が数値らしく見えるかどうかではなく、左側のオペランドによって決まります。

"19" のような値も文字列です。"19" % 10 では、Python は左側を書式文字列として解釈します。10 を使うプレースホルダーがないため、TypeError: not all arguments converted during string formatting が発生します。剰余を計算するには、先に文字列を整数へ変換します。メッセージに値を埋め込む場合は、書式プレースホルダーを使います。

%演算子の使われ方を確認する

よくある原因の一つは、input() から得た文字列や引用符で囲んだ文字列に % を適用することです。入力値を数値として剰余計算に使う場合は、先に int() で変換します。一方、文字列の書式設定が目的なら、文字列を左側に置き、対応するプレースホルダーを加えます。

次の例を実行してください。

このセクションのコードと表示されるラベルや出力は英語のままです。

message = "%s scored %d points." % ("Mina", 18)
print(message)

この例では名前と整数を書式設定し、Mina scored 18 points. と表示します。

数値の剰余計算では、計算の前に入力値を変換します。次の例では、未変換の文字列で発生するエラー文を捕捉してから、数値としての計算結果を示します。

age_text = "19"
try:
    age_text % 10
except TypeError as error:
    print(type(error).__name__ + ": " + str(error))

age = int(age_text)
print(age % 10)

int() は数字を整数に変換する関数であり、文字列書式指定子ではありません。数値以外の内容を含む文字列はこの方法では変換できません。入力値を信頼できない場合は、変換前に検証するか、変換エラーを処理してください。

書式指定子と値を対応させる

旧式の書式設定では、各プレースホルダーに対応する値が必要です。右側がタプルの場合、値は左から順にプレースホルダーと対応します。値がプレースホルダーより多いと、使われない値によって対象の TypeError が発生することがあります。値が少ない場合は別の書式設定エラーが発生します。個数の不一致がすべて同じエラーメッセージになるわけではありません。

たとえば、%s が2つあれば値も2つ必要です。使わない値を削除するか、その値を結果に含める必要があればプレースホルダーを追加します。文字列には %s、整数には %d を使います。すべての不一致が同じ原因だと決めつけず、値に合った指定子を選んでください。

文字列書式設定の方法を一つ選ぶ

% による書式設定では %s や %d のプレースホルダーを使います。.format() メソッドでは {} のような波括弧を使います。波括弧だけでは % による書式設定の対象にならないため、{0} を含む文字列に % で値を渡しても、その値は使われません。

式ごとに書式設定方法を一つ選びましょう。.format() を使う場合は、テンプレートに対してメソッドを呼び出し、値を渡します。% を使う場合は、テンプレートに対応するパーセント形式のプレースホルダーを置き、右側に値を指定します。Python のバージョンが対応していれば、f文字列も使えます。波括弧のテンプレートに % を適用しても、両方のプレースホルダー形式が処理されるわけではありません。

修正した式を確認する

式を左から順に確認します。左側のオペランドの型を特定し、% が剰余計算と書式設定のどちらを意味するか判断して、プレースホルダーの数と渡した値を照合します。次に、修正した最小の式を実行して結果を確認します。対象のエラーが残る場合は、余分な値がないか、数値を使うべき箇所に文字列を使っていないかを調べます。別のエラーに変わった場合は、その新しいエラーを個別に診断してください。

旧式の文字列書式設定を含む詳細については、Pythonの入出力に関するドキュメントを参照してください。