Translate

【python】NoneType' object has no attribute '○○'は何のエラー?【エラー対応】

こんにちは。

pythonでいろんなパッケージ関数を使用していると、いろいろなエラーに遭遇することがあります。pythonのエラーは大抵の場合IDEでコードを走らせるといろいろなエラー表示が出現するので、対応に困ってしまうことが多々あります。

今回はpythonで関数を使っているときに出てくる「NoneType' object has no attribute'○○'」とはどんなエラーを指すのかについて紹介していこうと思います。

NoneType' object has no attribute '○○'は存在しないデータを参照しようとしたときにエラー



この「NoneType' object has no attribute'○○'」のエラーは大抵の場合には、存在しないデータを参照しようとして起こるエラーであることが多い印象です。

何か関数なり何かのコードを走らせたときに、参照するものがないときには、返り値としてNoneTypeという値が格納されて返ってくることがあります。

骨格推定アルゴリムmediapipeで起こったNoneType' object has no attribute'○○'の例


このブログを読んで下さっている方の多くは理学療法士や動作解析に携わる人である思いますので、このNoneType' object has no attribute'○○'が起こる例について骨格推定アルゴリズムのmediapipeを運用しているときに発生したというシチュエーションで考えていきましょう。

参照するコードは過去の記事である、【初心者向け】とりあえずmediapipeを動かして座標データを取り出すところまでやってみた:https://himahimaknowledge.blogspot.com/2021/12/pandascsvpandas.html

で記載されているサンプルコードを例にしていきます。

このコードでは、動画データをスクリプト内に突っ込み、動画の中の人物を特定して、その一名分の各骨格位置のX座標、Y座標、Z座標を取得していくといった構成になっています。

その骨格位置の座標データを取得している部分のコードが以下のものなります。

        data1 = results.pose_landmarks.landmark[i].x
        data2 = results.pose_landmarks.landmark[i].y
        data3 = results.pose_landmarks.landmark[i].z

この部分では何が行われてるかというと、resultの中のpose_landmarksの中のlandmarkのi番目の座標のX座標、Y座標、Z座標を取得してきますという感じの処理になっています。

適切に投入した動画の中に人物が映っていれば、その人物の各関節のXYZ座標が変数名data1、data2、data3の中に格納されるという流れになります。

もし投入した動画の中に人物が映っていなかった場合には、当然骨格の推定が行われず、pose_landmarksの中のlandmarkのi番目の座標のX座標には何もデータが入らず、NoneTypeというデータ格納されてしまうことになります。

解決方法としては、該当する箇所のクラスから呼び出された関数の処理が適切に実行するように投入するデータを調整するか、クラスの初期設定の変数を変更することでエラーが解決す場合が多い印象です。

例えば例で紹介したmediapipeの場合には、投入する動画データ全体で必ず一人は人物が映っているように動画編集するといったことが対処法の一つになるといえます。またmediapipeを例にすると、サンプルコードの中で以下の部分があります。

mp_holistic.Holistic(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5)

この部分では、人物を同定する際の基準の厳しさなどを調整しており、この部分の基準を甘くすることで、動画全体でしっかりと人物を推定できるようするができ、エラーに対応することができます。

今回はmediapipeを例に「NoneType' object has no attribute'○○'」が発生する原因や対処法について説明しましたが、他の関数やクラスでも原因や対処法は割と共通していると思うので、別なプログラムで「NoneType' object has no attribute'○○'」のエラーで止まってしまっている方がいれば、一度入力した変数とパラメータ変数を見直してみると良いかもしれません。