Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’ の原因と解決方法【型変換で解決】

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’とは?ざっくりと3行で
  • Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’は、int型の値にstr型の値を+で足そうとしたときに発生するエラーだ。
  • 実務で一番多いのは、input()やフォーム、JSONから受け取った数字が文字列のままで、そこに整数を足してしまうケースだ。
  • 足す前にint()で数値へ変換するか、逆に文字列連結が目的ならstr()やf-stringで揃えれば直る。
Pythonでinput()の文字列に整数を足しTypeError: unsupported operand typeが出る4コマ漫画
①足し算しただけで赤いTypeErrorが表示され焦る。②入力値が文字列のままだと原因に気づく。③int()で数値へ変換して合計が正しく表示される。④デプロイ太郎がPythonは型に厳しいと補足する。

この4コマは、標準入力やフォームから受け取った値をそのまま計算に使ってしまう典型的な失敗を再現したケーススタディです。input()の戻り値は見た目が数字でも必ずstr型であり、Pythonは数値と文字列の暗黙的な型変換を行わない設計になっています。そのため整数に文字列を足した瞬間に処理が止まり、赤いトレースバックが表示されます。

この問題を軽視すると、開発中は気づかず本番のフォーム送信やバッチ処理で初めて例外が発生し、決済金額の集計やレポート生成が丸ごと落ちる事態になりかねません。ユーザーには500エラーだけが返り、原因の特定に時間を取られます。2コマ目のように変数の型を疑う視点を持てるかどうかが、復旧速度を大きく左右します。

解決の本質は、データがプログラムに入ってくる境界で型を確定させることにあります。int()float()で早期に数値化しておけば、以降の計算は安全になります。逆に表示用の文字列を作りたいだけなら、f-stringで整形するのが現代的な書き方と言えるでしょう。

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’の基本情報

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’は、整数(int)に文字列(str)を加算しようとしたときにPythonが処理を続行できず送出する型エラーです。まずは全体像を次の表で押さえておきましょう。

項目内容
エラーメッセージTypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
発生する言語・環境Python 3系全般(Python 3.12で確認)。CPython標準インタプリタ
エラーの意味+演算子に対して、int型とstr型という組み合わせはサポートされていない、という意味
主な原因input()やフォーム・JSON・CSVから受け取った数字が文字列のまま計算に使われている
解決の基本方針足す前にint()で数値化する。文字列連結が目的ならstr()やf-stringで型を揃える
ITKAGYO運営者デプロイ太郎のアイコン画像

入門書の写経中にいきなり出て戸惑う人が多いエラーです。コード自体は間違っていないのに、と焦りますよね。落ち着いて変数の型から確認していきましょう。

なぜPython TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’は発生するのか?

意外に見落とされがちですが、このメッセージが出るのは足し算の左側がint型のときだけです。左右を入れ替えて文字列を先に書くと、Pythonは別の文言(can only concatenate str)でエラーを返します。

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’のメッセージを直訳すると、+という演算に対してint型とstr型の組み合わせは非対応、という宣告です。Pythonは他言語のような暗黙の型変換を持たないため、数値と文字列をまたいだ加算をきっぱり拒否します。では、なぜ本来数値であるはずの値がstr型になってしまうのか。発生源ごとに3つのパターンへ分けて見ていきます。

パターン1:input()の戻り値をそのまま計算に使う

もっとも遭遇率が高いのが、標準入力から受け取った値をそのまま足すケースです。input()は入力内容がどれだけ数字らしく見えても、必ずstr型を返します。

# Python 3.12
total = 0                 # totalはint型
price = input("価格を入力: ")   # 例として "500" が入る(str型)
total = total + price     # int + str → ここでエラー
# TypeError: unsupported operand type(s) for +: 'int' and 'str'
print(total)

この例ではtotalが整数の0、priceが文字列の”500″です。左側がint型、右側がstr型の加算になるため、Pythonは型の橋渡しを拒否して例外を送出します。修正は、足す直前にint()で数値へ変換するだけです。

# Python 3.12(修正版)
total = 0
price = input("価格を入力: ")
total = total + int(price)   # int()で文字列を整数に変換してから加算
print(total)                 # 正しく合計が表示される

パターン2:JSONやAPIレスポンスの値が文字列で届く

外部APIやJSONファイルから読んだ値も、この型エラーの温床になります。JSON側で数値がクォートで囲まれていると、Pythonの辞書には文字列として格納されるためです。

# Python 3.12
data = {"count": "5"}        # JSON由来で "5" は文字列のまま
result = 10 + data["count"]  # int + str → エラー
# TypeError: unsupported operand type(s) for +: 'int' and 'str'

ここでの落とし穴は、辞書アクセス自体は成功してしまう点にあります。値の取得までは通り、加算の瞬間に初めて破綻するので、取得した値の型を早い段階で確定させておくのが安全です。

# Python 3.12(修正版)
data = {"count": "5"}
result = 10 + int(data["count"])   # 参照した値を整数に変換
print(result)                      # 15

パターン3:リストに数値と文字列が混在している

集計処理でループを回しているとき、要素の一部だけが文字列になっていると、その要素に到達した瞬間に停止します。CSVの1行だけ書式が違う、といった状況で起きがちです。

# Python 3.12
scores = [80, 90, "75"]   # 最後の要素だけ文字列
total = 0
for s in scores:
    total = total + s     # "75" に達した瞬間 int + str でエラー
# TypeError: unsupported operand type(s) for +: 'int' and 'str'

80と90の加算は問題なく進むため、原因の行が特定しづらいのが厄介な点です。要素ごとにint()を通すか、リスト生成の段階で型を揃えておけば、混在による事故を防げます。

# Python 3.12(修正版)
scores = [80, 90, "75"]
total = 0
for s in scores:
    total = total + int(s)   # 各要素を整数化してから加算
print(total)                 # 245
Python TypeError: unsupported operand type(s) for +の原因を解説するデプロイ太郎のアイコン画像

パターン1の入力値まわりは本当によく見かけます。現場では、外から入ってきた値はまず型を疑うクセをつけておくと事故がぐっと減りますよ。

Python TypeError: unsupported operand type(s) for +は演算子や左右の順序で表示が変わる?

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’は、加算する値の左右の順序や使う演算子によって、表示される文言が変化します。同じ根本原因でも見え方が違うため、下の対応を知っておくとデバッグが早くなります。

書いたコード(Python 3.12)表示されるエラーメッセージ
10 + “5”(intが左)TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
“5” + 10(strが左)TypeError: can only concatenate str (not “int”) to str
10 – “5”(減算)TypeError: unsupported operand type(s) for -: ‘int’ and ‘str’
“5” * “3”(文字列どうしの乗算)TypeError: can’t multiply sequence by non-int of type ‘str’

左側がint型のときだけ、今回のunsupported operand type(s)という文言になります。文字列を先に書いた場合はcan only concatenate strという別メッセージに切り替わりますが、直し方はどちらも同じで、型を揃えるだけです。なお乗算は例外的な挙動を示し、10 * "5"はエラーにならず文字列の反復として'5555555555'を返します。型エラーが出るのは"5" * "3"のように文字列どうしを掛けたときで、この差は覚えておくと混乱を避けられます。

FlaskやpandasでPython TypeError: unsupported operand type(s) for +が出るのはなぜ?

Flaskでの発生パターン

Flaskでフォーム送信を処理するとき、request.form.get()request.args.get()が返す値は常にstr型です。数量や金額をそのまま計算に回すと、ビュー関数の中でこの型エラーが起きます。テンプレート側の数字が正しく見えるだけに、原因を見誤りやすい場面です。

# Flask 3.x / Python 3.12
from flask import Flask, request

app = Flask(__name__)

@app.route("/add", methods=["POST"])
def add():
    qty = request.form.get("qty")   # 例: "3"(str型)
    base = 10
    # 誤: total = base + qty  → int + str でエラー
    total = base + int(qty)         # int()で数値化してから加算
    return str(total)
Flaskではフォーム値を受け取った直後にint(request.form.get("qty", 0))のように既定値付きで変換しておくと、未入力時のNoneも防げます。

pandasでの発生パターン

pandasでread_csv()を使うと、列に数字以外の文字や空白が混じっているだけで、その列のdtypeがobject(文字列扱い)のまま読み込まれます。この列に整数を足すと、要素単位でint型とstr型の加算が起き、同種の型エラーが発生します。表示上は数値に見えるため、df.dtypesで型を確認するのが第一歩です。

# pandas 2.x / Python 3.12
import pandas as pd

df = pd.DataFrame({"price": ["100", "200", "300"]})  # object型(文字列)
# 誤: df["price"] + 50  → 文字列列への加算で型エラー
df["price"] = pd.to_numeric(df["price"])   # 数値型へ変換
df["price"] = df["price"] + 50             # ここは安全に計算できる
print(df)
pandasではpd.to_numeric(df["price"], errors="coerce")を使うと、変換できない値をNaNにして処理を止めずに済みます。

数値化ではなく文字列を作りたいときの対処法は?

合計を計算したい場合(int()で数値化)

目的が計算なら、文字列側をint()やfloat()で数値へ変換します。小数を含むならfloat()を使い、整数だけならint()で十分です。変換元に数字以外が混じるとValueErrorになる点だけ注意しましょう。

# 誤り:文字列のまま加算
x = 10 + "5"          # TypeError

# 正しい:数値化して加算
x = 10 + int("5")     # 15
y = 3.5 + float("2")  # 5.5

画面表示用に連結したい場合(f-stringやstr())

数字と文字を1つのメッセージにまとめたいだけなら、数値側を文字列へ寄せます。現代のPythonではf-stringが読みやすく、型変換のミスも起きにくいのでおすすめです。

count = 5
# 誤り:intとstrの加算
msg = "在庫は" + count + "個です"   # TypeError

# 正しい:f-stringで整形
msg = f"在庫は{count}個です"        # 在庫は5個です
# もしくは str() で明示変換
msg = "在庫は" + str(count) + "個です"

Python TypeError: unsupported operand type(s) for +はどうデバッグすればいい?

Python TypeError: unsupported operand type(s) for +のデバッグは、加算に関わる変数の型を可視化することが最短ルートです。トレースバックの最終行が示すファイルと行番号を開き、その式に含まれる変数へtype()を当てて、どれがstr型なのかを突き止めます。

# Python 3.12
total = 0
price = input("価格を入力: ")

# 加算の直前で型を確認する
print(type(total), type(price))   # <class 'int'> <class 'str'>
print(repr(price))                # '500' のようにクォート付きなら文字列

total = total + int(price)
Python TypeError: unsupported operand type(s) for +のデバッグ方法を語るデプロイ太郎のアイコン画像

repr()で表示させると、クォートの有無で文字列かどうか一目でわかります。print(type(…))と合わせて使うのがデバッグの定番ですよ。

Python TypeError: unsupported operand type(s) for +を未然に防ぐには?

Python TypeError: unsupported operand type(s) for +を防ぐ鍵は、値がプログラムに入ってくる境界で型を確定させることです。型ヒントを付け、mypyのような静的解析ツールで検査すれば、計算前に型の食い違いを検知できます。ユーザー入力については、変換とエラーハンドリングをセットで書いておくと堅牢になります。

# Python 3.12
def add_price(base: int, raw: str) -> int:
    # 入力の境界で必ずintへ変換する
    try:
        return base + int(raw)
    except ValueError:
        # 数字でない入力はここで弾く
        raise ValueError(f"数値に変換できません: {raw!r}")

print(add_price(10, "5"))   # 15
型ヒントとmypyの併用で、int型を期待する箇所へstr型が渡る誤りを実行前に検出できます。

なぜPythonは数値と文字列を自動で連結してくれないのか?

Python TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’に初めて出会うと、JavaScriptを触った経験がある人ほど戸惑います。JavaScriptでは1 + "5"が文字列の”15″になり、暗黙の型変換で処理が進むからです。一方Pythonは、明示は暗黙に勝るという設計思想を貫き、あいまいな型変換をあえて禁じています。

これは不便に見えて、実はバグの温床を断つための安全装置です。数値の合計を出したいのか、文字列を連結したいのか、+という記号だけでは判断できません。Pythonはその判断を人間に委ね、意図しない結合を静かに実行してしまう事故を防いでいます。だからこそ開発者はint()str()、f-stringで目的を明示する必要があり、それがコードの読みやすさにもつながります。エラーを敵視するのではなく、型を意識させてくれる仕組みとして受け止めると、Pythonらしい書き方が身についていくでしょう。

Pythonの型に対する設計思想をまとめるデプロイ太郎のアイコン画像

このエラーは、Pythonが型をきちんと意識させてくれているサインでもあります。一つずつ変換を書けば必ず直るので、焦らずいきましょう。

よくある質問

Q
input()で受け取った数字が文字列になるのを防ぐには?
A

受け取った直後にint()float()で変換するのが確実です。age = int(input("年齢: "))のように一行でまとめておけば、以降の計算でstr型が紛れ込む心配がなくなります。小数を扱うならfloat()を選びましょう。

Q
sum()でリストを合計したらこのエラーが出るのはなぜですか?
A

リストの要素に文字列が1つでも混ざっているのが原因です。sum()は内部で0から順に加算するため、文字列要素に達した時点でint型とstr型の加算になります。sum(int(x) for x in items)のように各要素を変換すると解消します。

Q
mypyやLinterで実行前に防ぐことはできますか?
A

可能です。関数の引数や戻り値に型ヒントを付け、mypyで検査すればint型を期待する箇所へstr型が渡る誤りを実行前に指摘できます。ただし外部入力の値まではmypyも追い切れないため、境界でのint()変換と併用するのが実践的です。

Q
ユーザーが数値以外を入力してもエラーで落とさず処理するには?
A

変換処理をtryexcept ValueErrorで囲むのが基本です。int("abc")はValueErrorになるため、except側で既定値を代入したり再入力を促したりすれば、プログラム全体を停止させずに済みます。

Q
unsupported operand type(s) for +と can only concatenate strの違いは何ですか?
A

違いは加算する値の左右の順序だけで、根本原因は同じです。int型を左に書いた10 + "5"はunsupported operand type(s) for +となり、str型を左に書いた"5" + 10はcan only concatenate strになります。どちらも型を揃えれば解決します。

この記事と一緒に知っておきたいエラー解決

関連エラー この記事との関連
Python ValueError: invalid literal for int() 本記事の修正で使うint()に数字以外を渡すと発生する、対で押さえたいエラーです。
Python TypeError: ‘NoneType’ object is not subscriptable 同じTypeError一族で、型の取り違えが原因という点が共通します。
Python NameError: name ‘X’ is not defined 入門者が写経中につまずく代表的なPythonエラーで、原因の切り分け方が学べます。
Python ZeroDivisionError 同じく算術演算の途中で送出される例外で、入力値の検証が予防策になります。
PHP Fatal error: Uncaught TypeError: Unsupported operand types 他言語での同種の型エラーで、暗黙の型変換に対する考え方の違いが比較できます。

【出典】参考URL

https://docs.python.org/3/library/exceptions.html :TypeErrorの定義(不適切な型への操作で送出される)の根拠
https://docs.python.org/3/library/functions.html#int :int()による文字列から整数への変換仕様の根拠
https://www.pythonmorsels.com/can-only-concatenate-str/ :str+intとint+strで文言が変わる挙動の根拠

コメント

デプロイ太郎のSNSを見てみる!!