【问题标题】:how to get python the value from yield return如何从yield return中获取python值
【发布时间】:2015-03-18 15:28:44
【问题描述】:

开始学习python,无法从yield return中获取返回值。谁能帮我一个忙。

我只想将一个令牌从 url 传递给 WSHandler,并从 tonadoredis(github:https://github.com/leporo/tornado-redis) get 方法获取 uid。 然后 blpop 一个名为 "noticeT" + uid 的列表,当 "noticeTuid" 有一个新项目时,我希望它返回到浏览器。

但我的代码无法运行,我该如何解决我的问题?

class WSHandler(tornado.websocket.WebSocketHandler):
res = {'code':200, 'info': ''}

def initialize(self):
    self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=CONFIG['REDIS_PORT'], password=CONFIG['REDIS_AUTH'])
    self.logintoken = self.get_argument('logintoken')
    self.noticeModel = noticeModel(self.logintoken, self.c)

def open(self):
    print 'new connection'
    # uid = yield tornado.gen.Task(self.c.get, self.logintoken)
    # print uid
    self.res['info'] = self.noticeModel.getNotice()
    if self.res['info']:
        print self.res
        self.write_message(json_encode(self.res))
    else:
        self.res['code'] = 500
        self.res['info'] = 'error'
        self.write_message(json_encode(self.res))

def on_message(self, message):
    print 'message received %s' % message

def on_close(self):
    print 'connection closed'

def check_origin(self, origin):
    # print origin
    # return True
    parsed_origin = urlparse(origin)
    # print parsed_origin
    return parsed_origin.netloc.endswith("localhost")

noticeModel 代码是:

class noticeModel :
    def __init__(self, logintoken, redisobj):
        self.logintoken = logintoken
        self.redisobj = redisobj

    # @tornado.web.asynchronous
    @tornado.gen.engine
    def getNotice(self):
        # uid = self.setLoginUid()
        uid = yield tornado.gen.Task(self.redisobj.get, self.logintoken)
        print "getNotice uid is %s"% uid
        # if self.uid:
        print "getNotice logintoken is %s"% self.logintoken 
        key = "noticeT" + uid
        key = key.encode('utf-8')
        print 'listening key:%s'% key
        yield tornado.gen.Task(self.redisobj.blpop, key, 0)

    @tornado.gen.engine
    def setLoginUid(self):
        yield tornado.gen.Task(self.redisobj.get, self.logintoken)

【问题讨论】:

标签: python yield


【解决方案1】:

问题与yield 无关,它是您的配置参数。从堆栈跟踪

...
File "/Library/Python/2.7/site-packages/tornadoredis/connection.py", line 73, in connect
    sock.connect((self.host, self.port))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
TypeError: an integer is required

问题在于self.port 不是整数。查看port 的设置位置,

self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=CONFIG['REDIS_PORT'], password=CONFIG['REDIS_AUTH'])

CONFIG['REDIS_PORT'] 很可能是一个字符串,问题通过将其转换为int 得到解决

self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=int(CONFIG['REDIS_PORT']), password=CONFIG['REDIS_AUTH'])

【讨论】:

  • 请花点时间看看我的新答案~~
  • 如何删除该答案并将其作为新问题提出?您不必提及产量或港口的事情,这已经解决了,只是龙卷风问题。标记它蟒蛇和龙卷风。你会得到一双全新的眼睛看着它,并且可能有人知道如何修复它。顺便说一句,如果这是正确的答案,请接受它,以便未来的观众知道它有效。
  • redis 端口错误。我想要的是从 yield return 获得价值。现在我没有得到我想要的价值..
  • 再一次,这不是yield 的问题。错误告诉你问题出在哪里:"AttributeError: noticeModel instance has no attribute '_stack_context_handle_exception'"。我知道yield 并且我知道套接字,所以我回答了你之前的问题。我不使用龙卷风,所以无法帮助你。如果您将其写为龙卷风问题,那么龙卷风人们会注意到并回答。让想要帮助您的人更轻松。
  • 如果我撤销@tornado.web.asynchronous,在打开的WSHandler中,我打印self.res,iTerm得到这个:{'info': None, 'code': 200} getNotice uid is 89
【解决方案2】:

由于yield 返回一个生成器,您可以使用next 函数迭代其值!

下一个(迭代器[,默认])

通过调用next() 方法从迭代器中检索下一项。如果给出默认值,则在迭代器耗尽时返回,否则引发StopIteration

【讨论】:

    猜你喜欢
    • 2020-08-28
    • 1970-01-01
    • 2017-01-09
    • 2021-09-02
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多