将(yield)赋值给一个变量

10
首先,我想提到我对Python并不特别熟悉。最近我被迫熟悉一段代码样本,让我大吃一惊,但我无法“翻译”它。我查看了各种文档和文章,也没有帮助:
- “yield”关键字是什么? - 解释Python yield关键字 - yield语句 - yield表达式 这是涉及的函数的缩短版本:
@coroutine
def processMessage(receiver):
    global userID
    #...
    while True:
        msg = (yield)
        try:
            #...
        except Exception as err:
            #...

我无法理解它的作用,因此无法“步入”代码。我的问题是,“这个函数是做什么的?”和“这个函数要遵循哪些步骤?”

让我摸不着头脑的是msg = (yield)这一行。我不知道它想要实现什么。直觉告诉我它只是在接收新消息,但我不明白为什么。如果有人知道,并且如果我提供了足够的信息,我会非常感激他们能够给出一个解释。

try语句块:

if msg['event'] == 'message' and 'text' in msg and msg['peer'] is not None:
    if msg['sender']['username'] == username:
        userID = msg['receiver']['peer_id']
        config.read(fullpath + '/cfg/' + str(userID) + '.cfg')
        if config.has_section(str(userID)):
            log('Config found')
            readConfig()
            log('Config loaded')
        else:
            log('Config not found')
            writeConfig()
            log('New config created')
    if 'username' in msg['sender']:
        parse_text(msg['text'], msg['sender']['username'], msg['id'])

附言:receiver 是一个套接字接收器。


你想要实现什么目标? - johnashu
@johnashu,这是文件中唯一提到yield的地方。这是一个与telegram-cli交互的脚本。 - Pyromonk
2
yield 就是这样工作的。这是一个协程,在旧的、非异步的意义上。不过问题要问什么还不清楚。 - user2357112
@johnashu,当然,谢谢!我已经在我的初始帖子中添加了try语句代码。 - Pyromonk
2
@user2357112,对于一个旨在促进学习和研究的网站来说,它确实失败了。由于我在这门语言上缺乏足够的经验,我无法正确地呈现问题。这不是我的代码,所以我不能完整地呈现它。我应该怎么办?撞墙并诅咒每个给我投反对票和关闭问题的人吗?我已经研究了我的问题,并尽力做到最好地呈现它。我很抱歉没有做到完美,但我只是想学习。 - Pyromonk
显示剩余5条评论
1个回答

25

生成器中的语法variable = (yield some_value)执行以下操作:

  • some_value返回给调用它的代码(通过nextsend);
  • 当它再次被调用时(通过.next.send(another_value)),将another_value分配给variable并继续执行。

例如,假设您有一个生成器函数:

>>> def f():
...     while True:
...         given = (yield)
...         print("you sent me:", given)
...

现在,让我们称之为f。这将给我们返回一个生成器。

>>> g = f()

我们第一次使用生成器时无法向其发送数据。

>>> next(g)

此时它只是评估了yield... 当我们现在调用.send,它将从那个点继续,将我们发送给它的数据分配给给定的变量

>>> g.send("hello")
('you sent me:', 'hello')
>>> g.send("there")
('you sent me:', 'there')

在你的示例代码中,你有一个生成器:

  • 从外部接收到要处理的消息...会调用.send(some_msg);
  • 它将处理该消息,然后回馈给外部调用者,由它再提供另一条消息。

2
谢谢,亲切的先生!这是一个非常好的说明发生了什么。我在文档中找不到这样的用例。再次感谢,现在它有意义了。 - Pyromonk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接