2013-01-04 20 views
9

पैचिंग मैं अनुरोध 'रिस्पांस वर्ग (संस्करण 1.0.4, इस सवाल के रूप में वर्तमान) monkeypatch की जरूरत है, अतिरिक्त पद्धतियां जोड़ने का।अजगर बंदर

मैं इस कोड है:

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

में [2]: '1.0.4' : version__ आउट [2] अनुरोध .__ क्या यह आपके लिए भी सच है? अनुरोध – 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 __() टाइप एरर: सुपर (टाइप, ओबीजे): ओबीजे – user964375

उत्तर

12

तुम बस वर्ग के लिए सीधे अपने समारोह जोड़ने बेहतर होगा:

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

यह सिर्फ ठीक काम करता है:

>>> 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

प्रकार का उदाहरण या उप प्रकार होना चाहिए, मुझे पता है कि हम पाइथोनिस्टस __hate__ ओओपी हैं, लेकिन सबक्लासिंग के बारे में कैसे? – tenfishsticks

+0

@tenfishsticks: आपको अभी भी उस उप-वर्ग के साथ 'प्रतिक्रिया' वर्ग को प्रतिस्थापित करना होगा क्योंकि 'अनुरोध' एपीआई उस वर्ग के उदाहरण वापस कर देगी। एक विधि जोड़ने के लिए, मौजूदा वर्ग में विधि जोड़ने के लिए बस इतना आसान है। –

4

मुझे नहीं लगता कि आप बंदर-पैच उस प्रकार कर सकते हैं उसके जैसा। जब requests आयात करने, सभी these मॉड्यूल प्रारंभ कर रहे हैं। और जैसा कि पूरे पुस्तकालय from xy import Request अधिक से अधिक का उपयोग करता है, यह वास्तविक प्रकार के एक सटीक संदर्भ होगा। और उसके बाद, आप मॉडल मॉड्यूल के भीतर प्रतिक्रिया प्रकार को प्रतिस्थापित करते हैं, इसलिए केवल बाद के आयात प्रभावित होते हैं।

जब तक आप सभी मॉड्यूल के माध्यम से जाने के लिए और मैन्युअल रूप से अपने नए प्रकार के साथ अपने रिस्पांस संदर्भ की जगह, वे अभी भी मूल एक का उपयोग करेगा, अपने पैच बेकार बना रही है।

इसके बजाय, आप मूल प्रकार रखना, लेकिन यह सीधे का विस्तार करना चाहिए, के रूप में मार्टिन का सुझाव दिया।

+0

धन्यवाद। मैं अपनी कक्षा से सभी विधियों को पकड़ने और उन्हें मूल वर्ग में असाइन करने के लिए inspect.getmembers का उपयोग करूंगा। थोड़ा कम सुरुचिपूर्ण, लेकिन काम करेगा। – user964375

1

बस एक त्वरित फिक्स setattr का उपयोग कर, लेकिन यह एक बदसूरत (लेकिन शब्दार्थ @Martijn answer के बराबर) बिट:

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 
संबंधित मुद्दे