2014-11-20 16 views
11

मैं टर्ननाडो कोरआउटिन सीखने की कोशिश कर रहा हूं, लेकिन मुझे नीचे कोड का उपयोग करके त्रुटि है।टोरनाडो कोरआउट

Traceback (most recent call last): 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\web.py", line 1334, in _execute 
    result = yield result 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run 
    value = future.result() 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 109, in result 
    raise_exc_info(self._exc_info) 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 631, in run 
    yielded = self.gen.throw(*sys.exc_info()) 
    File "index.py", line 20, in get 
    x = yield 'test' 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run 
    value = future.result() 
    File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 111, in result 
    raise self._exception 
BadYieldError: yielded unknown object 'test' 

कोड:

from tornado.ioloop import IOLoop 
from tornado.web import RequestHandler, Application, url 
from tornado import gen 

class HelloHandler(RequestHandler): 
    @gen.coroutine 
    def get(self): 
     x = yield 'test' 
     self.render('hello.html') 


def make_app(): 
    return Application(
     [url(r"/", HelloHandler)], 
     debug = True 
    ) 

def main(): 
    app = make_app() 
    app.listen(8888) 
    IOLoop.instance().start() 

main() 
+0

आप 'x = yield' test'' पंक्ति पर क्या करने की कोशिश कर रहे हैं? –

+0

जो कि सिर्फ एक उदाहरण है, मैंने एक समारोह के परिणाम भी उत्पन्न करने की कोशिश की - परिणाम एक जैसा है, यह लाइन सिर्फ कोरआउट – klis87

उत्तर

26

रूप लुट्ज़ हॉर्न ने कहा, tornado.coroutine डेकोरेटर की आवश्यकता है कि आप केवल Future वस्तुओं या Future वस्तुओं से युक्त कुछ कंटेनरों उपज। इसलिए str उपज करने का प्रयास करने से एक त्रुटि बढ़ेगी। मुझे लगता है कि आप जिस टुकड़े को याद कर रहे हैं वह यह है कि एक कोरआउटिन के अंदर कोई भी जगह जहां आप yield something(), something पर कॉल करना चाहते हैं, या तो एक कोरआउटिन भी होनी चाहिए, या Future लौटा देना चाहिए। उदाहरण के लिए, अगर आप इस तरह अपने उदाहरण को ठीक कर सकते हैं:

from tornado.gen import Return 

class HelloHandler(RequestHandler): 
    @gen.coroutine 
    def get(self): 
     x = yield self.do_test() 
     self.render('hello.html') 

    @gen.coroutine 
    def do_test(self): 
     raise Return('test') 
     # return 'test' # Python 3.3+ 

या यहां तक ​​कि इस (हालांकि आम तौर पर आप इसे इस तरह नहीं करना चाहिए):

class HelloHandler(RequestHandler): 
    @gen.coroutine 
    def get(self): 
     x = yield self.do_test() 
     self.render('hello.html') 

    def do_test(self): 
     fut = Future() 
     fut.set_result("test") 
     return fut 
बेशक

, इन काल्पनिक उदाहरण हैं, चूंकि हम वास्तव में do_test में एसिंक्रोनस कुछ भी नहीं कर रहे हैं, इसलिए इसे कोरआउट बनाने का कोई कारण नहीं है। आम तौर पर आप वहां कुछ प्रकार के एसिंक्रोनस I/O कर रहे होंगे। उदाहरण के लिए:

class HelloHandler(RequestHandler): 
    @gen.coroutine 
    def get(self): 
     x = yield self.do_test() 
     self.render('hello.html') 

    @gen.coroutine 
    def do_test(self): 
     http_client = AsyncHTTPClient() 
     out = yield http_client.fetch("someurl.com") # fetch is a coroutine 
     raise Return(out.body) 
     # return out.body # Python 3.3+ 
+0

को कैसे लागू करें, महान उत्तर के लिए धन्यवाद, मैंने फ़ंक्शन do_test की शुरुआत में समय सोया, और सब कुछ काम करता है सिंक्रोनस कोड में, मुझे नींद (x) समाप्त होने के बाद निष्पादित किया जाता है। मैंने सोचा कि शायद यह फ़ंक्शन पृष्ठभूमि में किया जाता है, हालांकि यह मामला नहीं है ... फिर कोरआउट का उपयोग करने का क्या फायदा है? हो सकता है कि कोई अन्य उपयोगकर्ता पिछले उपयोगकर्ता की नींद से पहले एक ही समय में कनेक्शन खोल सके? – klis87

+2

@ user3575996 'उपज फ़ंक्शन() 'का उपयोग करके' कार्य()' पूरा होने तक कोरआउट प्रतीक्षा का निष्पादन होगा। हालांकि, यह * टर्ननाडो I/O पाश को अवरुद्ध नहीं करेगा, इसलिए यदि ग्राहकों से अन्य अनुरोध आते हैं, तो इस दौरान उन्हें संभाला जा सकता है। हालांकि, आप इसका परीक्षण करने के लिए 'time.sleep()' का उपयोग नहीं कर सकते हैं, क्योंकि यह एक अवरुद्ध कार्य है। आपको नींद के एक गैर-अवरुद्ध संस्करण का उपयोग करने की आवश्यकता है। उदाहरण के लिए [यह उत्तर] देखें (http://stackoverflow.com/a/23876402/2073595)। – dano

+0

धन्यवाद अब मैं सब कुछ समझता हूं :) – klis87

3

From the documentation:

तूफान में

अधिकांश अतुल्यकालिक कार्यों वापसी एक Future; इस वस्तु को उत्पन्न करने से इसका परिणाम मिलता है।

आप yield a list or dict of Futures, जो एक ही समय में शुरू किया जाएगा और समानांतर में चलाया जाएगा; जब वे सब काम पूरा होने पर एक सूची या परिणामों की dict लौटा दी जाएगी:

स्ट्रिंग "test" एक Future नहीं है। एक उपज करने की कोशिश करो।

+2

का परीक्षण करने के लिए है मान लें कि मैं डेटाबेस क्वेरी का परिणाम देना चाहता हूं, मान लें कि फ़ंक्शन get_all_users() यह करता है मैं, क्या आप कृपया मुझे एक उदाहरण दे सकते हैं क्योंकि टॉरनाडो उदाहरण कुछ बिल्ड-इन कक्षाओं जैसे AsyncHTTPClient() का उपयोग करते हैं, अपने – klis87

संबंधित मुद्दे