GCP上でサーバーの設定をせずにプログラムだけを実行できるCloudFuntions。
CloudFuntionsではいくつかのプログラム言語を利用できる。
その中のひとつ「Python」を使い、トリガーに「HTTP」を指定した場合、あるエラーに遭遇することがある。
TypeError: string indices must be integers
requestにstringではなく配列(list)や辞書型(dict)を渡すとこのエラーが発生する。
一体何が原因なのか。
そこで今回は、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法について解説する。
この記事を書いている人
記事を読むメリット
requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる現象
エラーが発生する現象はどのようなものか。
まず http request に以下の要素を持つjsonを格納してCloudFunctionsのトリガーとする。
"data":[{"key1":"val11","key2":"val12"}, {"key1":"val21","key2":"val22"}, {"key1":"val31","key2":"val32"}]
CloudFunctions側は request.get_json()
でrequestのjsonを読み解き、その中に格納した data
要素を呼ぶ。
そして data
の中の配列を順に print()
しようとしている。
request_json = request.get_json() json_data = request_json["data"] for v in json_data: print(v["key1"])
すると以下のエラーが発生する。
TypeError: string indices must be integers
「TypeError: string indices must be integers」になる原因
原因はエラーメッセージを見るとわかる。
TypeError: string indices must be integers
なので「string型の添字はint型でないとダメです」と言っている。
つまり print(v["key1"])
で辞書型変数の中身を表示しようとしたが、Pythonは辞書型(dict)ではなく文字列型として認識しているのでエラーになっている。
何故文字列として認識しているかというと、 request.get_json()
の仕様。
request.get_json()
で読み込まれた各要素は文字列として認識される。
つまりdata要素の中身は
[{"key1":"val11","key2":"val12"}, {"key1":"val21","key2":"val22"}, {"key1":"val31","key2":"val32"}]
という辞書型を複数格納した配列ではなく
'[{"key1":"val11","key2":"val12"}, {"key1":"val21","key2":"val22"}, {"key1":"val31","key2":"val32"}]'
という長い文字列として認識されているので、辞書型のつもりで要素を呼ぶとエラーになってしまう。
「TypeError: string indices must be integers」の解決方法
「TypeError: string indices must be integers」の解決方法だが、文字列を配列(list)や辞書型(dict)として認識させればいい。
文字列を配列(list)や辞書型(dict)として認識させるには eval()
を使う。
request_json = request.get_json() json_data = eval(request_json["data"]) for v in json_data: print(v["key1"])
こうすることで eval()
に指定した文字列を式として評価し直すので、文字列を配列(list)や辞書型(dict)として認識させることができる。
eval()
については過去記事を参考。
あわせて読みたい
requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法 まとめ
CloudFunctionsのPythonを利用する際、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因は送ったデータが文字列として認識されているから。
解決方法として、取り込んだ文字列に eval()
を適用するとlistやdictとして認識してくれる。
Pythonの外側からデータを渡す方法として、iniファイルを読む方法についても記事があるので、もし気になったら見て欲しい。