2

時間の経過とともに、stdlib制限を克服したり、不足している機能を追加したりするために、Pythonのいくつかのメソッドをオーバーライドする必要があることに気付きました。

いずれの場合も、ラッパー関数を追加し、モジュールの元のメソッドをラッパーに置き換えました(ラッパーは元のメソッドを呼び出していました)。

なぜ私はこれをしましたか?メソッドへのすべての呼び出しが、他のサードパーティモジュールから呼び出された場合でも、私の新しいバージョンを使用していることを確認してください。

モンキーパッチは悪いことかもしれませんが、私の質問は、注意して使用した場合にこれが役立つかどうかです。つまり:

  • 元のモジュールが更新されたときに何も欠落していないことを保証して、元のメソッドを引き続き呼び出します
  • メソッドの元の「意味」を変更していません

例:

このようなことをすることは、私にはまともなオーバーライドのように見えますが、他の人がそれらをどのように見ているか、特に許容できるモンキーパッチと見なされるべきものとそうでないものを確認したいと思います。

4

2 に答える 2

7

これらのどれもモンキーパッチを必要としないようです。それらはすべて、より優れた、より堅牢で信頼性の高いソリューションを備えているようです。

ロギングハンドラーの追加は簡単です。モンキーパッチはありません。

オープンの修正はこの方法で行われます。

from io import open

それは簡単でした。パッチはありません。

にログインしos.system()ますか?単純な「ラッパー」関数は、複雑なパッチよりもはるかに優れていると思います。subprocess.Popenさらに、それが推奨される代替品であるため、私はを使用します。

OSの違いをマスクするために欠落しているメソッドを追加する(のようにos.chown())は、try/exceptのより良い使用法のようです。しかし、それは私だけです。私は暗黙的ではなく明示的が好きです。

結局のところ、私はまだモンキーパッチの正当な理由を見ることができません。

os.systemモンキーパッチに依存しすぎたため、レガシーコード(のような)に固定されるのは嫌です。


「サブクラス」の概念は、クラスだけでなくモジュールにも適用されます。(a)既存のモジュールをインポートおよび(b)拡張する独自のモジュールを簡単に作成できます。次に、新しいモジュールが追加機能を提供するため、それらを使用します。モンキーパッチをする必要はありません。

これらが他のサードパーティモジュールから呼び出された場合でも

恐ろしい考え。組み込みの機能を変更することで、別のモジュールを簡単に壊すことができます。あなたが他のモジュールを読んでいて、monkeypatchesが壊れないことを確信しているなら、あなたが見つけたのはこれです。

  1. 「その他」のモジュールには、カスタマイズの余地があったはずです。「依存性注入」または戦略設計パターンの場所が必要でした。いい考え。

  2. これを見つけたら、「その他」のモジュールを修正して、このカスタマイズを可能にすることができます。オブジェクトを変更する方法を説明するドキュメントの変更と同じくらい簡単かもしれません。カスタマイズを挿入することは、構築のための追加のパラメーターである可能性があります。

  3. 次に、改訂されたモジュールを作成者に提供して、作成者がモジュールの小さな更新をサポートするかどうかを確認できます。多くのクラスは、拡張機能の「依存性注入」または戦略設計をサポートする追加のヘルプを使用できます。

他のモジュールを読んでおらず、monkeypatchesが機能するかどうかわからない場合は、 ...まあ...monkeypatchesが何も壊さないことを願っています。

于 2010-08-10T15:05:41.923 に答える
3

モンキーパッチは、「最も悪が少ない」場合があります。ほとんどの場合、テスト容易性のために適切に設計されていないサブシステムを使用するコードをテストする必要がある場合(依存性注入などをサポートしていません)。そのような場合、テストハーネスで(非常に一時的に、幸運にも)モンキーパッチを適用し、テストを分離する(つまり、統合テストではなく単体テストにする)目的で、ほとんどの場合、モックまたは偽物を使用してモンキーパッチを適用します。

この「悪いが、もっと悪いかもしれない」ユースケースはあなたの例には当てはまらないようです-アプリケーションレベルのコードを編集して適切なラッパー関数(たとえば、myos.chown裸ではなく)を呼び出し、ラッパー関数は、アプリケーションレベルのコードと標準ライブラリ(またはラップしているサードパーティの拡張機能-この点で標準ライブラリに特別なことは何もありません)の間にあるos.chown独自の中間モジュール(など)で機能します。myown

「アプリケーションレベルのコード」が実際に制御されていない場合、問題のある状況が1つ発生する可能性があります。これは、変更したくないサードパーティのサブシステムです。それにもかかわらず、そのような状況では、(標準ライブラリ関数を直接ではなく)ラッパーを呼び出すようにサードパーティのサブシステムを変更する方が、長期的にははるかに生産的であることがわかりました。もちろん、サードパーティのメンテナに変更を送信します。問題のサブシステムでは、変更をサブシステムの次のリリースにロールバックし、すべての人の生活が向上します(変更が受け入れられると、他のユーザーによって定期的に保守およびテストされるため、含まれています!-)。

(補足として、このようなラッパーは標準ライブラリに差分として送信する価値があるかもしれませんが、標準ライブラリは非常にゆっくりと慎重に進化し、特にPython 2ラインではもはや進化しないため、これ別のケースです。 、2.7はその行の最後であり、機能が凍結されているため)。

もちろん、これはすべてオープンソース文化を前提としています。いくつかの不思議な理由で、クローズドソースのサードパーティサブシステムを使用している場合、つまり維持できない可能性がある場合は、モンキーパッチがそれほど悪ではない可能性がある別の状況にあります(ただし、それは戦略的制御を失うことの悪のためですおそらく維持できないコードを信頼することによる開発のそれ自体が非常に大きな悪です;-)。クローズドソースであり、それ自体がPythonで記述されたサードパーティのパッケージを使用してこのような状況に陥ったことは一度もありません(後者の条件が当てはまらない場合は、monkeypatchesは役に立ちません;-)。

ここで、「クローズドソース」の実用的な定義は非常に厳密であることに注意してください。たとえば、12年以上前のMicrosoftでさえ、Visual C ++を使用したMFCなどのライブラリのソースを配布しました(製品は当時呼ばれていました)。ソースを再配布することはできませんでしたが、それでも、ソースが手元にあるので、ひどい制限やバグに遭遇した場合は、修正することができます(そして、将来のリリースのために変更を送信し、変更を次のように公開します著作権で保護されたコードがまったく含まれていない限り、差分です。些細なことではありませんが、実行可能です)。

そのようなアプローチが「最も悪が少ない」という厳格な範囲をはるかに超えたモンキーパッチは、動的言語のユーザーのよくある間違いです。自分自身がその罠に陥らないように注意してください。

于 2010-08-10T15:30:51.683 に答える