【问题标题】:Accessing yielded variable only once [closed]仅访问一次产生的变量[关闭]
【发布时间】:2019-09-30 19:53:05
【问题描述】:

所以我们有这样一个函数:

def infinite_sequence():
  num = 0
  while True:
    yield num
    time.sleep(1)
    num += 1

以下代码:

    for num in infinite_sequence():
      print(num)

将导致打印:

0
1
2
3
4
...

现在想象 infinite_sequence() 在后台运行,我只需要打印实际的 num 变量。

例如:运行一分钟后 infinite_sequence() 结果应该是 60

我该怎么做?

【问题讨论】:

  • 您只想打印最后一个值?
  • 听起来像是 XY 问题。如果您想知道自“动作 X”以来已经过去了多少秒,只需使用时间戳来跟踪它。您甚至可以将其包装在一个类中,然后使用同一个实例来查询“自动作 X 以来的秒数”。
  • 没有“最后一个”值;你到底是如何“停止”infinite_sequence
  • 您需要一个单独的执行线程来更新您可以独立查询的共享变量。
  • 没有生成“最后一个”值。这些值仅在您请求时生成。它们不是提前生成的,因此没有“当前”值,它们也没有存储在任何地方,这样您就可以要求以前生成的值。这听起来绝对像是一个 XY 问题。你有问题 X 并且你正在询问尝试的解决方案 Y(一个休眠的生成器)。你能告诉我们关于问题 X 的事吗?

标签: python yield


【解决方案1】:

生成器不能自己“运行”(在后台或其他地方)。但是如果一个线程正在迭代它(处理延迟可以忽略不计),它也可以将该值存储在某个地方:

def stash(it,box):
  for x in it:
    box[0]=x
    # more fast operations on x…

# elsewhere
box=[None]
th=threading.Thread(target=stash,args=(infinite_sequence(),box))
th.start()
while …:
  latest=box[0]
  # operate on latest

至少在 CPython 中,对列表元素的非同步访问是安全的,当然在您使用它之前它可能已经过时了。

【讨论】:

    猜你喜欢
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2015-06-25
    相关资源
    最近更新 更多