3

Pythonでは、この用語monkey patchは実行時のクラスまたはモジュールの動的な変更のみを指します。初心者として、Pythonのコンテキストでこの用語を理解するのは非常に困難です。誰かが実際の例で私に説明できますか?

  1. クラスの動的変更
  2. 実行時のモジュールの動的変更

どのシナリオでそのようなタスクを実行する必要があるかを理解するために、実際の例(可能な限り単純)を主張していますか?

4

2 に答える 2

6

モンキー パッチは、既存のコードが引き続き実行されるように内部のグローバルな変更を行う方法ですが、動作は変更されます。

組み込みstrコマンドの動作を変更する非常に簡単な例:

b.py

def foo(msg):
    s = str(msg)
    print s, type(s)

a.py

import b

b.foo('foo')

# monkey-patch 
import __builtin__
__builtin__.str = unicode

b.foo('foo')

# Results:
#foo <type 'str'>
#foo <type 'unicode'>

aモジュールは、代わりに使用するパッチを適用することにより、コマンドを使用して他のコードの動作を変更しましstrunicodeb.pyのコードにアクセスできないふりをするので、これが必要になります。それは、単に使用するだけで変更できない巨大なパッケージであった可能性があります。しかし、動作を変更する新しいコードを呼び出すことができます。

geventの実例

>>> import gevent
>>> from gevent import socket
>>> urls = ['www.google.com', 'www.example.com', 'www.python.org']
>>> jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls]
>>> gevent.joinall(jobs, timeout=2)
>>> [job.value for job in jobs]
['74.125.79.106', '208.77.188.166', '82.94.164.162']  

上記の例では、ソケット操作に gevent.socket を使用しました。標準のソケット モジュールが使用された場合、DNS 要求がシーケンシャルになるため、完了までに 3 倍の時間がかかります。greenlets 内で標準の socket モジュールを使用すると、gevent はかなり無意味になります。ソケットの上に構築されたモジュールとパッケージはどうなるでしょうか?

それがモンキーパッチの目的です。gevent.monkey の関数は、標準ソケット モジュールの関数とクラスを、対応する協調モジュールに慎重に置き換えます。そうすれば、gevent を認識しないモジュールでも、マルチ グリーンレット環境で実行することでメリットを得ることができます。

>>> from gevent import monkey; monkey.patch_socket()
>>> import urllib2 # it's usable from multiple greenlets now
于 2012-08-15T21:18:42.083 に答える
3

モンキー パッチを使用した実際の例を次に示します。

  1. 単体テスト。多くの場合、実際のオブジェクトにパッチを適用するスタブ/モックを作成して、テストのニーズを尊重するように動作を変更すると便利です。たとえば、Object.method1()動作をテストしたいとします。メソッドは、文字列または None を返すことができます。ということで、モンキーパッチの登場です。method1コードを 1 行だけ含むスタブ メソッドに置き換えますreturn None
  2. 実行時のコードの変更/拡張。おそらく、そのようなユースケースの最も良い例は、かなり人気のある python gevent ライブラリです。モンキーパッチを使用して、標準のソケットモジュールを gevent が必要とする方法で動作させます。ここにソースコードがあります。
  3. 実行時にオブジェクトにパッチを適用します。オブジェクトを簡単かつ迅速に変更すると便利な場合があります。その後、オブジェクトは、アプリケーションの他の部分で使用されるインターフェイスに適合する必要があります。関数を使用してPythonで簡単に実行できますsetattr。これは多くの場合、アプリケーションのアーキテクチャが悪いことを意味し、設計上の適切な決定ではありません
于 2012-08-15T21:18:50.840 に答える