📝

pythonのクラス変数に外部関数を使うとTypeError:(省略) but 1 was givenになる問題を考える

2023/08/29に公開

https://qiita.com/items/f8b749930ed0af16d76c


お詫び

Qiitaの元記事にて、区切り線を「---」で書いている場所があり、これがZennの記法に干渉して一部うまく表示できない記事がある事を認識しています。
全ての記事を精査しきれていないため、お手数ですがお見かけの際は教えていただけると大変喜びます。


変更前タイトル:pythonのクラス変数に外部関数を使うときにTypeError: function name takes 0 positional arguments but 1 was givenとエラーになってしまう問題を考える

タイトルが長いですが、言いたい事はそのままです。

問題

def outer():
    return 'outer'

class inner():
    function = outer
    def call_outer_function(self):
        print(self.function())

inner().function()

これを実施すると、タイトルの通りエラーになります。

解決

def outer():
    return 'outer'

class inner():
    function = lambda self:outer()
    def call_outer_function(self):
        print(self.function())

inner().function()

クラス内でメソッドを使う場合、暗示的にselfが渡されます。
selfを捨てることで解決させようという発想です。

展開

lambda式で書いているので分かりにくいんですが、要するにこういう事をやってます。

def outer():
    return 'outer'

class inner():
    def function(self):
        outer()

    def call_outer_function(self):
        print(self.function())

inner().function()

こちらはよく見る形だと思います。

実例

def outer(input)
を作っていて、クラス内から呼び出した時にif isinstance(input, '期待するobject')をやらなかったせいで、この関数ではエラーにならず通ってしまい、別の場所で問題になった時に追いかけるのにやたらと時間が掛かりました。
可能であれば引数をバリデーションする癖をつけておきましょう。
たったこれだけの事なんですが、えらい目に遭いました。

読了後いいね!をお願いします。

どれだけの方に読んでもらっているか知りたいので、お手数をおかけしますがご協力いただけると嬉しいです。

GitHubで編集を提案

Discussion