これは私に尋ねられたインタビューの質問でした. それが意味をなさない場合でも、私を罰しないでください。彼女は尋ねた:
「Python に既存のサードパーティ ライブラリがあり、その中に関数 foo() があります。既存のモジュールにインポートした後、その関数を変更するにはどうすればよいですか?」
これは私に尋ねられたインタビューの質問でした. それが意味をなさない場合でも、私を罰しないでください。彼女は尋ねた:
「Python に既存のサードパーティ ライブラリがあり、その中に関数 foo() があります。既存のモジュールにインポートした後、その関数を変更するにはどうすればよいですか?」
これはモンキーパッチと呼ばれます。つまり、関数を保持する変数に代入するだけです。
import existingmodule
existingmodule.foo = lambda *args, **kwargs: "You fail it"
これが実際に正しい答えになることはめったにありません。何かを独自の関数でラップするか、独自の実装を別の場所に提供するか、継承を使用する (クラスのメソッドの場合) 方がはるかに優れています。
これを行う唯一の理由は、変更された動作をライブラリ自体のコード (または他のサードパーティ コード) に反映する必要がある場合です。もしそうなら、よくテストしてください。通常、独自のフォークを作成するよりも優れたアプローチです。そうは言っても、コードをパッチとして提出するのは良い考えかもしれません。そのため、プロジェクトに受け入れられた場合、それをサポートするだけではありません。
最も一般的なアプローチはモンキーパッチです(参照:stackoverflow:モンキーパッチとは)
例えば:
>>> import os
>>> os.listdir('.')
['file_a', 'file_b']
>>> os.listdir = lambda folder: ['nothing in here, nope!']
>>> os.listdir('.')
['nothing in here, nope!']
PyCon 2012で、このテーマについて非常に良い話があり、 YouTubeで見ることができます。
この話はまた、モンキーパッチが役立つ場所の非常に良い例を示しています。特定のことを行うサードパーティのライブラリがあるとします。これを行うには、このスクリプトをrootとして実行する必要がありますが、実際の機能にはroot権限は必要ありません。現在、サードパーティのライブラリはこれをでチェックしている可能性がありますos.geteuid() == 0
。このライブラリを使用するコードにモンキーパッチを適用することで、geteuid
この制限を回避するためにルートである偽物にオーバーライドできます。
モンキーパッチを使用すると、ライブラリをすばやく修正できます。バグレポートの提出とパッチの待機には時間がかかる場合があるため、ライブラリのソースコードを掘り下げることなく、この方法で自分自身を助けることができます。