Python:TypeError: hoge() takes 1 positional argument but 2 were given

Context & Probrem

雑多に書いていた関数群をリファクタリングしてクラスとしてまとめていた時にタイトルのようなエラーが出た。

TypeError: hoge() takes 1 positional argument but 2 were given

あれ、おかしいな、と。エラーの内容としてはhogeメソッドが受け取る予定の引数は1つしかないが、2つ渡されているぞ、ということ。コードを見返しても2つも引数指定なんてしていないしどういうこっちゃとなった。

Solution

selfをメソッド引数に生やし忘れてた。言語仕様としてselfを書かないとこうなる。

# 実行時にエラーを吐くコード
class fuga:
   def hoge(xxx):
        pass # なんかしらの処理
# 実行できちゃうコード
class fuga:
   def hoge(self, xxx):
        pass # なんかしらの処理

fuga.hoge()という要領でメソッドの呼び出しを行うと、hogeの第一引数にはfugaが入る仕様になっている。仕様を知らないとなぜエラーが出ているのか表面的にはわからず混乱する事になる。Pythonのこの仕様はプログラマからも評判があまり良くないようで、変更するような提案がなされているらしいが、Pythonの生みの親Guidoによってなぜselfを明記する仕様が重要なことなのかを説明するブログもある。あまり単純な話ではないようで自分もまだ完全に咀嚼しきれていないので言及は避ける。

Reference

大変勉強になった記事