Pythonでは、この用語monkey patch
は実行時のクラスまたはモジュールの動的な変更のみを指します。初心者として、Pythonのコンテキストでこの用語を理解するのは非常に困難です。誰かが実際の例で私に説明できますか?
- クラスの動的変更
- 実行時のモジュールの動的変更
どのシナリオでそのようなタスクを実行する必要があるかを理解するために、実際の例(可能な限り単純)を主張していますか?
Pythonでは、この用語monkey patch
は実行時のクラスまたはモジュールの動的な変更のみを指します。初心者として、Pythonのコンテキストでこの用語を理解するのは非常に困難です。誰かが実際の例で私に説明できますか?
どのシナリオでそのようなタスクを実行する必要があるかを理解するために、実際の例(可能な限り単純)を主張していますか?
モンキー パッチは、既存のコードが引き続き実行されるように内部のグローバルな変更を行う方法ですが、動作は変更されます。
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
モジュールは、代わりに使用するパッチを適用することにより、コマンドを使用して他のコードの動作を変更しましstr
たunicode
。b.py
のコードにアクセスできないふりをするので、これが必要になります。それは、単に使用するだけで変更できない巨大なパッケージであった可能性があります。しかし、動作を変更する新しいコードを呼び出すことができます。
>>> 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
モンキー パッチを使用した実際の例を次に示します。
Object.method1()
動作をテストしたいとします。メソッドは、文字列または None を返すことができます。ということで、モンキーパッチの登場です。method1
コードを 1 行だけ含むスタブ メソッドに置き換えますreturn None
。setattr
。これは多くの場合、アプリケーションのアーキテクチャが悪いことを意味し、設計上の適切な決定ではありません。