簡単な例を見てみましょう:
class A:
def __init__(self, flag):
self.flag = flag
def func(self):
print self.flag
a = A(1)
b = A(2)
callback_a = a.func
callback_b = b.func
callback_a()
callback_b()
結果は次のとおりです。
1
2
期待通りに動作します。しかし、質問があります。C では、コールバック関数はポインターとして渡されます。Python では、呼び出し元が関数のアドレスを知ることができるように、同様の方法でこれを行う必要があります。しかし、私の例では、関数ポインターが渡されるだけでなく、パラメーター (self) も渡されます。同じクラスの同じメソッドが異なる結果を出力しているためです。そこで、私の質問は次のとおりです。
Python のこのようなメソッドは、メモリ内にコピーが 1 つしかありませんか? 私の意味は、どのメソッドのコードにもコピーが 1 つしかなく、私の例ではメソッド自体が複製されないということです。コピーは 1 つだけであるべきだと思いますが、ここではより多くの入力を得るためにこの質問をしています。
Python ではすべてがオブジェクトであることを覚えています。つまり、私の例では、異なるパラメータを持つ 2 つの関数インスタンスがありますが、コードのコピーは 1 つだけでしょうか?
ベストアンサー1
Python では、コールバックは単にメンバー関数への参照ではありません。 代わりに、コールバックは作成時に参照したオブジェクトに「バインド」されます。 したがって、a.func
にバインドされた呼び出し可能オブジェクトを作成しa
、b.func
にバインドされた呼び出し可能オブジェクトを作成しますb
。
Python ではfunc()
メモリ内に の実装が 1 つだけ必要ですが、バインディングを実現するために実行時に 1 つ以上の「トランポリン」関数が作成される可能性が高いです (この内部の詳細はよくわかりませんし、Python の実装によっても異なるでしょう)。
印刷するid(callback_a)
とid(callback_b)
異なる結果が得られ、それらが実際には異なる呼び出し可能なオブジェクトであることがわかります。