5

Pythonでは、事前定義された関数を属性としてクラスに割り当てることができます。

def fish_slap(fish):
    # do something

class dance(object):
    dance_move=fish_slap

しかし、私たちが言うことをしようとすると

d=dance()
d.dance_move("Halibut")

次のエラーが発生します

TypeError: fish_slap() takes exactly 1 arguement (2 given)

Pythonはこれをオブジェクトメソッドと見なし、暗黙の「self」引数を提供しているようです。公平に言えば、この方法で関数を属性として割り当てることは、クラス内で関数を直接定義することと同等であることを私は学んだようです。これは便利な機能であることがわかります。

しかし、この場合、これは私が望むものではありません。私のアプリケーションでは、さまざまなクラスとしてエンコードされた統計モデルがあり、提供されたデータに対してモデルパラメータをトレーニングするための独自の「train」メソッドもあります。これを行うには、の値を最小化(または最大化)したい目的関数を提供する必要があります。単純な目的関数の例は次のとおりです。

def RMSE(predicted,observed):
    "Root mean squared error"
    return sp.sqrt(sp.mean((predicted-observed)**2))

ここで、SciPyはspとしてインポートされています。これらの目的関数は、単一の.pyファイルで定義され、コード全体で使用され、暗黙の「self」引数を持つクラスメソッドとしてではなく、スタンドアロン関数として自然に存在します。

たとえば、モデルオブジェクトが実行する後続の作業でその関数を使用できるように、目的の目的関数を属性として設定できるようにしたい。

some_model=SomeModel(initial_parameter_values_guess) 
some_model.objective_function = RMSE
some_model.train(training_data)
predictions_RMSE = some_model.predict()
some_mode.objective_function = MAE
predictions_MAE = some_model.predict()

この例では、トレーニングの引数として目的関数を渡すことができるようですが、私のアプリケーションでは、やりたいことがもっとたくさんあり、目的関数を設定/取得できる方が理にかなっているようです。引数として繰り返し提供するよりも。

この基本的な動作を実現するための回避策はいくつもありますが、最も現実的なアプローチは何ですか?

私の現在のコードはpython2とpython3に準拠していることに注意してください。バージョン固有の解決策がある場合は、それを指摘してください。matplotlibを使用できるようにするためにpython2で実行していますが、そのモジュールとは別に、コードがpython3と互換性があることを確認しようとしています。

4

1 に答える 1

8

staticmethodを使用できます

class dance(object):
    dance_move=staticmethod(fish_slap)

インスタンスstaticmethodの属性に割り当てる場合は、を使用する必要がないことに注意してください。

>>> def move():
...     print "disco party!"
... 
>>> class dance(object):
...     dance_move = staticmethod(move)
... 
>>> d = dance()
>>> d.dance_move()
disco party!
>>> d.break_it_down = move
>>> d.break_it_down()
disco party!
于 2013-02-24T21:37:10.613 に答える