HOWTO · Python
TypeError を解決する: Python では整数が必要です
このチュートリアルでは TypeError について説明します: Python では整数が必要です。
このページの内容
TypeError: an integer is required メッセージは、Python コードが関数に誤った型の値を渡したときに表示されます。関数は整数を要求しましたが、通常は文字列などの別の値が渡されました。このエラーは、文字列の文字を chr() に渡すループや、数値ではなくテキストとして渡された設定値など、数多くの類似した呼び出しで発生します。
このガイドでは、メッセージの実際の意味、原因となった値の見つけ方、コードで意図した動作に合う修正方法の選び方を説明します。
TypeError: an integer is required の意味
この文言の TypeError は、1つの不正な引数を報告します。関数またはメソッドは、Unicode コードポイント、回数、最大長、ファイルモードなど、そのパラメーターの1つが整数でなければならないと宣言していますが、実際に受け取った値は整数ではありませんでした。このチェックは呼び出しの解析時に行われるため、関数は何も処理を実行せずに失敗します。
Python は、発生させた関数や実行しているバージョンによって、同じ失敗をいくつかの文言で表現します。an integer is required、an integer is required (got type str)、'str' object cannot be interpreted as an integer が表示されることがあります。これらはすべて TypeError であり、意味も同じです。引数の型がパラメーターの要件と一致しなかったということです。
unsupported operand type(s) 系のメッセージと混同しないでください。"10" + 5 のような式では TypeError: can only concatenate str (not "int") to str が発生しますが、これは結合できない2つのオペランドを表すもので、同じ TypeError であっても診断内容も修正方法も異なります。
このエラーが発生する理由
組み込み関数と、標準ライブラリの C 実装部分は、引数を厳密に解析します。整数が必要な位置に文字列が見つかると、その呼び出しは直ちに停止します。最小限の例は collections.deque の maxlen パラメーターで、これは整数でなければなりません。
このセクションのコードと表示されるラベルや出力は英語のままです。
from collections import deque
try:
queue = deque([], "3")
except TypeError as error:
print(f"{type(error).__name__}: {error}")
TypeError: an integer is required
よりよくある同じ間違いは、文字列を反復処理するループ内で chr() を呼び出すことです。文字列を反復処理すると1文字の文字列が得られますが、chr() は整数のコードポイントを Unicode 文字に対応付けるため、ループが生成する各文字は拒否されます。
try:
for char in "42":
print(chr(char))
except TypeError as error:
print(f"{type(error).__name__}: {error}")
TypeError: 'str' object cannot be interpreted as an integer
同じ種類のバグですが、文言は異なります。どちらの場合も、修正は同じように始めます。整数ではない引数を見つけてください。
関数に渡された値を診断する方法
トレースバックは下から上に読みます。最後の行には例外の型とメッセージが示され、その1つ上の行には失敗した呼び出しが示されます。そこから、引数がどこから来たのか、ループ変数、input()、設定ファイル、JSON の文字列フィールドなどをたどります。テキストとして読み取られた値は文字列として渡される一方、JSON などの解析済み形式では、すでに型付きの値が得られる場合があるからです。
メッセージに渡した値の名前が示されていない場合は、呼び出し箇所で repr() と type() を出力して値を調べます。
このセクションのコードと表示されるラベルや出力は英語のままです。
for char in "42":
print(f"{char!r} has type {type(char).__name__}; its code point is {ord(char)}")
'4' has type str; its code point is 52
'2' has type str; its code point is 50
これで不一致が明確になりました。ループは chr() に文字列 '4'(型は str)を渡していますが、ord() は実際に処理に必要な整数、つまりコードポイント 52 を示します。引数の実際の型と値を特定できれば、適切な修正方法を選ぶのは簡単です。
入力を安全に修正する方法
意図した処理に合う修正を選びます。
- 文字列の数字や文字を表示するだけなら、その値を直接出力します。
print(char)にchr()呼び出しは必要ありません。 - 指定したコードポイントに対応する文字を取得するには、
chr()に実際の整数を渡します。ord()は文字のコードポイントを返し、int()は数字の文字列をその数値に変換します。次の例を実行してください。
このセクションのコードと表示されるラベルや出力は英語のままです。
for char in "42":
print(char, "->", chr(ord(char)))
4 -> 4
2 -> 2
設定ファイルやコマンドラインから取得される maxlen のようなパラメーターについては、呼び出しの前に int() でテキストを一度変換し、その結果を渡します。
int() は整数として解釈できる文字列だけを受け付けます。信頼できない入力では、先に str.isdigit() で確認し、不正な値が変換処理に到達しないようにします。
text = "53"
if text.isdigit():
print(chr(int(text)))
else:
print("not a whole number")
5
事前確認だけでは不十分な場合は、変換の失敗を直接処理します。不適切な文字列に int() を適用すると ValueError が発生します。これは、最初に発生した TypeError とは別の例外です。
try:
number = int("10.5")
except ValueError as error:
print(f"{type(error).__name__}: {error}")
ValueError: invalid literal for int() with base 10: '10.5'
修正を確認し、関連する型エラーを回避する
コードを再実行し、残っているトレースバックがあれば最後の行を読みます。それにより、まだ型の問題があるのか、別のバグに移行したのかが分かります。maxlen に整数を渡すと、先ほどの失敗は動作する deque になります。
このセクションのコードと表示されるラベルや出力は英語のままです。
from collections import deque
queue = deque(["x", "y", "z"], maxlen=3)
queue.append("w")
print(list(queue))
['y', 'z', 'w']
次の点に注意してください。
- 各引数の型をシグネチャーに合わせます。
chr()は整数のコードポイントを受け取り、ord()は文字を受け取り、int()は数値文字列を整数に変換します。 int()から発生するValueErrorは、最初のTypeErrorではありません。一方を捕捉しても他方は隠れないため、それぞれ発生源で処理してください。can only concatenateやunsupported operand type(s)のようなメッセージは、不適切な引数ではなく、式内で型が混在していることを表しています。これらには別の修正が必要です。
このエラーは行き止まりではなく、道標です。どの値が誤った型を持っていたか分かれば、適切な変換、あるいは変換しないという選択肢に自然とたどり着けます。