defer.execute वास्तव में एक अवरुद्ध ढंग से फ़ंक्शन निष्पादित करता है, एक ही धागे में और आप सही में है कि defer.execute(f, args, kwargs)
कि defer.execute
एक कॉलबैक कि errback पड़ा है अगर समारोह निकाल वापस आ जाएगी छोड़कर defer.succeed(f(*args, **kwargs))
के रूप में ही करता हैं एफ एक अपवाद फेंकता है। इस बीच, आपके defer.succeed उदाहरण में, अगर समारोह एक अपवाद फेंक दिया, यह बाहर फैल जाएगा, जो वांछित नहीं हो सकता है।
समझ की आसानी के लिए, मैं सिर्फ defer.execute के स्रोत यहाँ पेस्ट करना होगा:
def execute(callable, *args, **kw):
"""Create a deferred from a callable and arguments.
Call the given function with the given arguments. Return a deferred which
has been fired with its callback as the result of that invocation or its
errback with a Failure for the exception thrown.
"""
try:
result = callable(*args, **kw)
except:
return fail()
else:
return succeed(result)
दूसरे शब्दों में, defer.execute
के रूप में एक आस्थगित एक अवरुद्ध समारोह के परिणाम लेने के लिए सिर्फ एक शॉर्टकट है जो आप कर सकते हैं फिर कॉलबैक/गलती जोड़ें। कॉलबैक सामान्य चेनिंग अर्थशास्त्र के साथ निकाल दिया जाएगा। यह थोड़ा पागल लगता है, लेकिन कॉलबैक जोड़ने से पहले डिफर्रेड 'आग' कर सकते हैं और कॉलबैक अभी भी कॉल किए जाएंगे।
तो अपने सवाल का जवाब देने, क्यों यह उपयोगी है? खैर, defer.execute
दोनों परीक्षण/मॉकिंग के साथ-साथ सिंक्रोनस कोड के साथ एसिंक एपीआई को एकीकृत करने के लिए उपयोगी है।
भी उपयोगी है defer.maybeDeferred
जो फ़ंक्शन को कॉल करता है और फिर यदि फ़ंक्शन पहले से ही स्थगित लौटाता है तो इसे वापस लौटाता है, अन्यथा defer.execute
के समान कार्य करता है। यह तब उपयोगी होता है जब आप एक एपीआई लिखते हैं जो कॉल करने योग्य से अपेक्षा करता है कि जब आपको बुलाया जाता है तो आपको स्थगित कर दिया जाता है, और आप सामान्य अवरोधन कार्यों को भी स्वीकार करने में सक्षम होना चाहते हैं।
उदाहरण के लिए, कहें कि आपके पास एक ऐसा एप्लिकेशन था जो पृष्ठों को लाता था और इसके साथ चीजें करता था। और, किसी कारण से, आपको इसे एक विशिष्ट उपयोग केस के लिए एक सिंक्रोनस फ़ैशन में चलाने की आवश्यकता होती है, जैसे सिंगल-शॉट क्रोंटैब स्क्रिप्ट में, या डब्लूएसजीआई एप्लिकेशन में अनुरोध के जवाब में, लेकिन फिर भी वही कोडबेस रखें। यदि आपका कोड इस तरह देखा, यह किया जा सकता है:
from twisted.internet import defer
from twisted.web.client import getPage
def process_feed(url, getter=getPage):
d = defer.maybeDeferred(getter, url)
d.addCallback(_process_feed)
def _process_feed(result):
pass # do something with result here
एक तुल्यकालिक संदर्भ में इस चलाने के लिए, रिएक्टर के बिना, तो आप सिर्फ एक वैकल्पिक गेटर समारोह गुजर सकता है, इसलिए जैसे:
from urllib2 import urlopen
def synchronous_getter(url):
resp = urlopen(url)
result = resp.read()
resp.close()
return result
+ Defer.maybe व्याख्या करने के लिए 1 –