2014-10-17 3 views
0

저는 파이썬 2.7과 토네이도 3.2를 실험 해 왔습니다. 나는이 작동하는 간단한 코 루틴 예제를 얻기 위해 노력했지만, 많은 행운없이 : URL을 컬링 때 늘릴 수 없습니다. 코 루틴을 사용할 때의 작업으로 돌아 가기

import tornado.web 
from tornado.gen import coroutine 
from tornado.httpclient import AsyncHTTPClient 
from tornado.gen import Return 

class MainHandler(tornado.web.RequestHandler): 

    # Tried with and without @asynchronous 
    @tornado.web.asynchronous 
    def get(self): 
      data = MainService().get_google_data() 
      self.write(data) 


class MainService: 

    @coroutine 
    def get_google_data(self): 
      response = yield AsyncHTTPClient().fetch("http://www.google.com") 
      raise Return(value = 'hello') 

나는이 '안녕하세요'쓰는 것 예상.

... 
File "/vagrant/venv/lib/python2.7/site-packages/tornado/web.py", line 656, in write 
raise TypeError("write() only accepts bytes, unicode, and dict objects") 
TypeError: write() only accepts bytes, unicode, and dict objects 

분명히, Future를 돌려되고 있지만, 미래에 result()를 호출하면 다른 예외가 발생합니다 : 대신, 내가 할 DummyFuture does not support blocking for results

문서는 위해 코 루틴에서 값을 반환하는 말 토네이도, Return 예외를 발생시킵니다. 소스 코드를 보면, 실제로 예상 한 것 같습니다. 그러나, 그것을 실행할 때, 그것은 작동하지 않는 것 같습니다.

이 점에 대해 통찰력을주십시오!

+0

Runner.run()에 깊이 파고 들자면, 내가하는 일에 대한 결론에 도달했을 수도 있습니다. – MrSilverSnorkel

+0

제쳐두고, 당신은''Return ('hello')'를 올릴 수 있습니다. 'value ='가 필요 없습니다. – dano

+0

@dano 그래, 값 = 정당한 이유없이 거기에 있었다. 러너를 들여다 보니, 언뜻보기에 내가 생각했던 것을하지 못한다. 그것은 당신이 당신의 대답에서 말하는 것이라고 생각하는 미래를 되돌려줍니다. – MrSilverSnorkel

답변

4

당신은 get_google_data()에 전화를 yield해야합니다

class MainHandler(tornado.web.RequestHandler): 

    @coroutine 
    def get(self): 
     data = yield MainService().get_google_data() 
     self.write(data) 

토네이도 코 루틴은 항상 Future을 반환합니다. Future의 결과가 나타날 때까지 yield을 호출합니다. yield이 없으면 코 루틴이 완료 될 때까지 기다리지 않고 바로 Future이 다시 종료됩니다. get_google_data 외에도 get 방법에 @coroutine 데코레이터를 사용해야합니다. @asynchronous 장식자는 일반적으로 코 루틴이 아닌 콜백을 사용하려는 경우에 사용됩니다.

+0

그래,이 말이 맞아. 따라서 데이터 액세스 객체를 호출하는 서비스를 호출하는 핸들러가 있고 데이터 액세스 객체가 coroutine을 구현하면 모든 호출이 스택 위로 올라와 coroutines로 장식되어야합니다. – MrSilverSnorkel

+0

@MrSilverSnorkel 네, 코 루틴은 일반적으로 "바이러스 성"입니다. 일단 당신이 그것을 추가하면, 그것을 부르는 모든 것은 하나가되고 싶어한다. 실제로 콜링 컨텍스트를 coroutine으로 사용하지 않고 코 루틴을 호출하는 방법도 있지만 "coroutine_call (yield)"보다 조금 더 복잡합니다. – dano

+0

감사합니다. 내 생각에 음식을주었습니다. 호출 컨텍스트를 coroutine으로 사용하지 않고 coroutine을 호출하는 이러한 방법 중 하나의 예 – MrSilverSnorkel

관련 문제