2013-01-04 6 views
9

追加のメソッドを追加するには、リクエストのレスポンスクラス(バージョン1.0.4、現在の質問)をmonkeypatchする必要があります。Python monkey patching

私はこのコードを持っている:

import requests 

class Response(requests.models.Response): 
    def hmm(self): 
     return 'ok' 

requests.models.Response = Response 

r = requests.get('http://bbc.co.uk') 

print r 

元の応答は、スーパー()を呼び出したときにそれが失敗した - https://github.com/kennethreitz/requests/blob/master/requests/models.py#L391

私はそれが混乱してしまうので、私はクラスを交換してきたように、これは、だと思う、私は感じます私は何かばかげた、何か考えているように?前もって感謝します。

+0

: アウトversion__要求.__ [2]: '1.0.4' これはあなたにも当てはまりますか?このコードは、以前のバージョンのリクエストで私のために働いていました – user964375

+0

どのようなエラーで失敗しますか? – Eloff

+0

ファイル "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py"、391行目、__init__ スーパー(応答、自己).__ init __() TypeError:super(type、obj):objは型のインスタンスまたはサブタイプでなければならない – user964375

答えて

12

あなただけのクラスに直接あなたの機能を追加したほうが良いだろう:私はあなたがそのタイプ猿パッチことができるとは思わない

>>> import requests 
>>> def hmm(self): 
...  return 'ok' 
... 
>>> requests.models.Response.hmm = hmm 
>>> r = requests.get('http://bbc.co.uk') 
>>> print r 
<Response [200]> 
>>> r.hmm() 
'ok' 
>>> requests.__version__ 
'1.0.4' 
+0

私はPythonistas __hate__ OOPを知っていますが、サブクラス化はどうですか? – tenfishsticks

+0

@tenfishsticks: 'requests' APIがそのクラスのインスタンスを返すので、' Response'クラスをそのサブクラスに置き換える必要があります。メソッドを追加するには、メソッドを既存のクラスに追加するほうが簡単です。 –

4

:これは正常に動作します

def hmm(self): 
    return 'ok' 
requests.models.Response.hmm = hmm 

そうですね。 requestsをインポートすると、すべてtheseモジュールが初期化されます。そして、ライブラリ全体がfrom xy import Requestを何度も使っているので、実際のタイプを正確に参照します。その後、モデルモジュール内のレスポンスタイプを置き換えるので、後続のインポートだけが影響を受けます。

すべてのモジュールを調べて、手動でレスポンスリファレンスを新しいタイプに置き換えない限り、元のものをそのまま使用してパッチを無用にします。

代わりに、元のタイプはそのままにして、直接展開する必要があります。

+0

ありがとうございます。 inspect.getmembersを使用してクラスからすべてのメソッドを取得し、それらを元のクラスに割り当てます。少しエレガントですが、動作します。 – user964375

1
setattrを使用してだけで簡単に修正

が、それは少し醜い(しかし@Martijn answerと同じ意味)です:[2]では

def hmm(self): 
    return 'OK - %s' % self.status_code 

setattr(requests.models.Response, 'hmm', hmm) 

r = requests.get('http://bbc.co.uk') 
print r.hmm() 
# prints 
# OK - 200 
関連する問題