2016-08-30 5 views
10

私はPythonsのオブジェクトモデルでa presentationを読んでいました.1つのスライド(数字9)では、Pythonsの関数が記述子であると主張していました。関数記述子はどのように機能しますか?

def mul(x, y): 
    return x * y 

mul2 = mul.__get__(2) 
mul2(3) # 6 

は今、私は関数が__get__を定義しているので、私はの説明セクションで説明したように、それが記述され、ポイントがなされていることを理解する:彼は説明するために提示例は、私が書いたこの1に似ていますPythonのドキュメント。

私が理解していないのは、コールの結果がどのように出力されているかです。

答えて

12

これは、クラスに動的に関数を追加することをサポートするためにPythonが行うことです。

__get__は、関数オブジェクト(通常、クラスのインスタンスにドットアクセス.介して行わ)Pythonはと暗黙(通常selfとして認識)インスタンスを渡す方法に関数を変えていくように呼び出された場合最初の引数。

>>> mul2 
<bound method mul of 2> 
:明示的
コール __get__と明示的 機能 xの最初の引数としてバインドされている「インスタンスの 2を渡し、ここ 2は、「インスタンス」 self考えられている、あなたの場合は

、あなたが

これは、インスタンス2にバインドされたメソッドで、1つの期待される引数で乗算を生成します。呼び出しは2(バインドされた引数はxに割り当てられます)にanythそれ以外の場合は引数yとして指定します。

通常、function()は、それが提供する適切な引数を持つ__call__だ呼び出す:プラスとして

mul.__call__(2, 3) # 6 

を、機能のための__get__のPython実装はPythonのドキュメントのDescriptor HOWTO文書で提供されています。ここで

あなたは__get__が呼び出されたときに起こるtypes.MethodTypeの使用、と、変換を見ることができます:

class Function(object): 
    . . . 
    def __get__(self, obj, objtype=None): 
     "Simulate func_descr_get() in Objects/funcobject.c" 
     return types.MethodType(self, obj, objtype) 

そして、興味をそそられ、訪問者のためのソースコードがObjects/funcobject.cに位置しています。

このディスクリプタが存在しないかのように、不要な手間であるクラスに動的に関数を追加したい場合はいつでも、関数を自動的にtypes.MethodTypeにラップする必要があります。

関連する問題