スコルの知恵袋

主にプログラミング関係の気になったこと等をまとめたブログ

インスタンスメソッドをクラスから直接呼び出すとどうなる?[Python3]

問題

つぎのPythonコードを実行したら出力はどうなるだろう

class Foo:
    def bar(self, *args):
        return args

a = Foo.bar('hello', 'world')
a

答えは,

('world',)

である.あれ,'hello'はどこへ行った……

解説

ポイントはインスタンスメソッドをクラスから直接呼び出しているところにある.

インスタンスメソッドをインスタンスから呼び出すと,第1引数selfには暗黙的にそのインスタンス自身が代入される.

class Foo:
    def bar(self):
        return self  # self をそのまま返す

f = Foo()
a = f.bar()
f is a
True

しかし,インスタンスメソッドをクラスから直接呼び出すと,selfには上のような暗黙的な代入は行われず,
メソッドに与えられた第1引数が素直に代入される.

a = Foo.bar('hello')
a
'hello'

なので,今回の問題の例では,第1引数selfに文字列'hello'が代入され,
可変長引数*argsには'world'のみが渡されるため,出力が('world',)となった.

このことから次が言える

class Foo:
    def bar(self, *args, **kwargs):
        ~なんらかの処理~

f = Foo()

であるとき,

f.bar(*args, **kwargs)

Foo.bar(f, *args, **kwargs)

は同じ