【问题标题】:Printing function every second?每秒打印功能?
【发布时间】:2015-09-22 06:55:00
【问题描述】:

我的目标是能够运行一个函数并每秒打印一次结果。我希望它看起来像这样:

打印

“在 {seconds} 你有 {value}。” // 如果值来自另一个函数,我们也可以假设该值上升了一个常数,但由另一个函数计算。

并继续在每一秒的新行上打印它。到目前为止,我遇到了两个问题。

1) 我无法编写每秒打印一个值的函数。我尝试过使用 threadingtime,但我无法让它工作。

2)如果我将睡眠定时器设置为 1 秒,则必须花费几毫秒(或更短的时间测量)来计算函数,然后才能打印上述行。我想,经过几十万次计算,我的时间和值将不再准确。

到目前为止,我是从另一个线程借来的:

 def update(i):
  threading.Timer(1, update, [i]).start()
  sys.stdout.write(str(i)+'\r')
  sys.stdout.flush()
  print(i)
  i += 1

这个功能不像我想象的那样工作。我认为它每次都会将 i 的值加一,然后将该值放回 update() 函数中。它只是每次都打印出相同的值。老实说,我不知道为什么,我试着逐行弄清楚,但可惜我做不到。

谢谢

-2.0

【问题讨论】:

标签: python multithreading python-3.x time


【解决方案1】:

threading.Timer(1, update, [i]).start()移动到函数末尾,它会正确打印递增值。

如果您想长期获得 1 Hz 的准确频率,请将上次执行时间 (time.time()) 存储在附加参数中,并补偿传递给 Timer 的间隔,例如:

def update(i, last_time=time.time()-1):
    sys.stdout.write(str(i)+'\r')
    sys.stdout.flush()
    print(i)
    i += 1
    cur_time = time.time()
    threading.Timer(2-(cur_time-last_time), update, [i, cur_time]).start()

即使您有一些局部漂移(由于线程的调度并不总是即时的),它也会在下一步中恢复。

您可以在i += 1 之后添加time.sleep(random.random()*0.6) 自己尝试。

【讨论】:

  • 当我运行此代码时,它会打印出正确的数字,但会打印两次。示例:00、11、22、33、44、55、66、77、88、99、1010、1111 等。我尝试操作代码,但我不明白为什么会这样。它似乎每行打印两次“i”值。
  • 那是因为它写了两次:一次是print,一次是sys.stdout.write
  • 我尝试删除 printsys.stdout.write 语句,但随后它开始在每个操作中打印出两个数字。它会在不同的行上(同时)打印 1 和 2,然后是 3 和 4,然后是 5 和 6……等等。我只有一个打印语句,所以我不确定为什么会这样。它似乎也每 2 秒打印一次,所以时机正确,但我试图让它每行打印一个数字。
【解决方案2】:

通过精确计算预期时刻来避免累积误差,但调用 sleep 函数时使用到当前间隔结束的实际剩余时间。

import datetime
import time

tstep = datetime.timedelta(seconds=1)
tnext = datetime.datetime.now() + tstep
while True:
    print "something"
    tdiff = tnext - datetime.datetime.now()
    time.sleep(tdiff.total_seconds())
    tnext = tnext + tstep

如果您的处理时间保持在 1 秒以下,则此过程会正确补偿它。

【讨论】:

    猜你喜欢
    • 2021-11-19
    • 2018-07-10
    • 1970-01-01
    • 2023-03-18
    • 2014-11-29
    • 2022-01-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多