私はライブラリにいくつかの非常に基本的な機能(scikit-learn)を追加しようとしています。しかし、私は直接ライブラリ自体を変更したくないと思っています。それは、自分のテストでも、機能をオン/オフにする機能を持っていると思います.b)これはおそらく、ライブラリのメインコードベース。Pythonでライブラリからクラスを完全に猿にパッチすることは可能ですか?
基本クラス(この場合はsklearn.base.BaseEstimator)をモンキーパッチして、ライブラリ内の他のクラスをクラスからインポートまたは派生させると、代わりに自分の変更されたクラスを取得するようにしたい。ここでは、私がこれまで持っているものです。
import sklearn
from sklearn.base import BaseEstimator
from sklearn import base
class InstrumentedEstimator(sklearn.base.BaseEstimator):
def __init__(self, *args, **kwargs):
print 'called'
super(InstrumentedEstimator, self).__init__(*args, **kwargs)
sklearn.base.BaseEstimator = InstrumentedEstimator
base.BaseEstimator = InstrumentedEstimator
BaseEstimator = InstrumentedEstimator
from sklearn.ensemble import RandomForestClassifier
RandomForestClassifier()
これは動作しません - すなわち、RandomForestClassifier()
はcalled
を印刷しません。ここでの主な理由は、RandomForestClassifier
の階層を見ると、BaseEstimatorから派生する最終的な親クラスがsklearn.ensemble.base.BaseEnsemble
であることが考えられます。
from ..base import BaseEstimator
がサル・パッチにPythonで輸入品のこのスタイルも可能です:sklearn /アンサンブル/ base.pyを見てみると、一つは以下の見ていますか?さらに重要なのは、プログラムのコンテキスト内では、明らかにどこでどのようにインポートされるかにかかわらず、このクラスのすべてのインスタンスをサルパッチすることは可能ですか?
理想的には、エンドゲームは、このようなものになるだろう:
import my_module
from sklearn.(anything) import SomeEstimator
SomeEstimator() # this runs my code in addition to SomeEstimator's code
...
Doh!私は '__init__'の欠如に気付かなかったとは信じられません。私はちょうどそれが1つを持っていると仮定したと思います! –