2016-02-10 17 views
6

クラスのインスタンスを作成するときに関数と等しいクラス属性を定義すると、その属性はバインドされたメソッドになります。誰かが私にこの行動の理由を説明できますか?Python - クラス属性としての関数がバインドされたメソッドになる

In [9]: def func(): 
    ...:  pass 
    ...: 

In [10]: class A(object): 
    ....:  f = func 
    ....:  

In [11]: a = A() 

In [12]: a.f 
Out[12]: <bound method A.func of <__main__.A object at 0x104add190>> 

In [13]: a.f() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-13-19134f1ad9a8> in <module>() 
----> 1 a.f() 
    global a.f = <bound method A.func of <__main__.A object at 0x104add190>> 

TypeError: func() takes no arguments (1 given) 

答えて

7

属性fに機能を割り当てました。関数がクラスの中にあるのは、それがメソッド、特にバインドされたメソッド(オブジェクトにバインドされているため、further explanation here)になります。

クラスのメソッドそれが特異的ではないに語っていますしない限り、少なくとも一つのパラメータ(self)を受け取る - class methods and static methods参照 - この理由でエラーが(それはdef func():として定義されていますよう)funcが引数をとらないことを言いますが、1を受けた(selfあなたがやりたい)

、あなたはstatic method

def func(): 
    pass 

class A(object): 
    f = staticmethod(func) 
を使用していることのpythonを教えてください
1

PythonはメッセージベースのOOシステムありません。代わりに、JavaScriptと同様に、プロパティはファーストクラスの関数に解決され、呼び出されます。発見されたように、その振る舞いはその機構では少し異なります。 Pythonで

要件は、方法は、それがメソッドとして呼び出されたとき自動的に関連付けられたインスタンスが供給される通常selfと呼ばれる少なくとも1つのパラメータを、有することです。

さらに(おそらく問題点に)、Pythonはdef f..又はf = some_func()インスタンス部材バインディングを確立用いて区別しません。おそらくこれはクラス外の振る舞いと一致します。

この例では、インスタンスに関数を割り当てると 'インスタンスメソッドのように扱うことが期待されます'。どちらの場合でも呼び出されるのは、まったく同じ - パラメータなしの関数です。そのようなものの将来の使用法のみが関連しています。

JavaScriptとは異なり、Pythonはメソッドとオブジェクトの関連付けをバインドされたメソッドの概念によって処理します。メソッドは常にメソッドにバインドされているため解決されます。

バインドされたメソッドを返すa.fの動作は、バインドされたオブジェクトを最初にselfという名前のパラメーターに自動的に供給するための関数です。関数のソースとは関係なく実行されます。この場合、パラメーターなしの関数は、selfパラメーターを受け入れないため、「束縛されている」ときには使用できません。

方法ないないの基礎となるソースは、引数としてインスタンスを受け入れるの最小要件を満たしているため、デモンストレーションとして、以下は同じように失敗します:g()を呼び出すこの場合

g = a.f 
g() 

がされfunc(a)と同じです。比較のため


、Java(登録商標)、C#、ルビー、及びスモールトークは、メッセージベースのオブジェクト指向システムである - これらのオブジェクトは、「名前」でメソッドを呼び出すように言われている、代わりの方法を解決する(または関数)を呼び出すことができる値として定義します。

関連する問題