2016-03-23 6 views
1

以下に示すように、クラスのデフォルトの動作を提供したいと思います。バインドされていないメソッド<method>は、<class>インスタンスを最初の引数として呼び出さなければなりません。

import numpy as np 

class Test: 
    def __init__(self, my_method=None): 
     self.my_method = my_method or np.min 

Test().my_method([1, 2, 3]) # >>> 1 

コードは期待通りに機能します。一緒に簡単にコードの保守のためのすべてのデフォルト値を維持するために、私は

import numpy as np 

class Test: 
    default_method = np.min 

    def __init__(self, my_method=None): 
     self.my_method = my_method or Test.default_method 

Test().my_method([1, 2, 3]) # >>> TypeError 

にコードを変更したいが、my_methodへの呼び出しは、エラーメッセージunbound method amin() must be called with Test instance as first argument (got list instance instead)で失敗します。奇妙なことに、np.minではなく、minという組み込み関数を使用すると、コードが正常に動作します。つまり、次のコードは期待どおりに動作します。

import numpy as np 

class Test: 
    default_method = min # no np. 

    def __init__(self, my_method=None): 
     self.my_method = my_method or Test.default_method 

Test().my_method([1, 2, 3]) # >>> 1 

何が欠けていますか?

+1

Python2では、新しいスタイルクラス宣言を使用する必要があります。これらは 'class Test(object):'のように 'object'から派生しています。私は古いスタイルのクラスのセマンティクスをかなり忘れていますが、これがあなたの問題に耐えられると思います。 – msw

+0

@msw、ヒンジのおかげで。しかし、新しいスタイルのクラスではこの問題は解決されません。 –

答えて

2

クラスオブジェクトに属性として格納されている関数は、Pythonによってメソッドとして扱われます。 Python 2では、最初の引数をクラスのインスタンスにする必要があります(インスタンスを介して属性が要求された場合に自動的に渡されます)。 Python 3では、バインドされていないメソッドはそのような方法で引数をチェックしなくなりました。

Pythonの2の問題を回避するには、staticmethoddefault_method値をラップしてみてください:

class Test(object): 
    default_method = staticmethod(np.min) 
    #... 

あなたもself.default_methodを使用することができますので、これは、でも、Pythonの3に悪い考えではないかもしれません明示的にクラスの名前を付けるのではなく、

コードがminでは機能しますが、np.minではない理由は、実装が異なるためです。記述子として

>>> type(min) 
<class 'builtin_function_or_method'> 
>>> type(np.min) 
<class 'function'> 

正規関数(np.minのような)行為、彼らは(したがって、あなたの問題を引き起こしていた「結合」の行動を取得)クラスの属性です:あなたはそれらのtype sのことがわかります。 minのような組み込み関数は、記述子プロトコルをサポートしていないため、問題は発生しません。

+0

それは素晴らしいです、ありがとう! –

関連する問題

 関連する問題