繁体   English   中英

Python生成器返回一系列时间

[英]Python generator to return series of times

我希望这不在Python生成器的能力范围之内,但我想构建一个生成器,以便每次调用该函数时,它都会在下一分钟返回直到结束时间。

因此,该函数将读取开始时间和结束时间,并以分钟为单位返回时间,直到覆盖了之间的所有时间为止。

如何实施? TIA

datetime模块非常棒。 您需要了解两种数据类型: datetimetimedelta datetime是一个时间点,而timedelta是一个时间段。 基本上,我在这里要做的是一次开始,一次结束(作为datetime时间对象),并逐渐增加1分钟。

这显然有一个警告,您必须弄清楚如何将开始时间和结束时间计入datetime时间。 有多种方法可以执行此操作: 现在 ,从UTC时间戳通过构造函数 ,等等。

import datetime

def minute_range(start, end, step=1):
   cur = start
   while cur < end:
      yield cur
      cur += datetime.timedelta(minutes=step)

仅仅因为更少的代码行总是更好(tm):

def minutes(s, e):
    secs = (e - s).seconds 
    return (s + datetime.timedelta(minutes = x) for x in xrange(secs / 60 + 1))

像这样使用它:

>>> today = datetime.datetime(2012, 1, 31, 15, 20)
>>> for m in minutes(today, today + datetime.timedelta(minutes = 5)):
...     print m
2012-01-31 15:20:00
2012-01-31 15:21:00
2012-01-31 15:22:00
2012-01-31 15:23:00
2012-01-31 15:24:00
2012-01-31 15:25:00

这是我用于此目的的生成器。 可以增强它使其在一段时间后停止,或者可以将该逻辑保留在调用代码或其他迭代器中。

import time

def sleep_gen(period):
    """Generator, returning not sooner, then period seconds since last call.

    returned value: time of next planned start (no need to use this value)
    """
    next_time = 0
    while True:
        now = time.time()
        sleep_time = max(next_time - now, 0)
        next_time = now + sleep_time + period
        time.sleep(sleep_time)
        yield next_time

您可以使用以下代码测试行为

import plac
import time
from itertools import count, izip
import random

#sleep_gen to be defined here

@plac.annotations(
    period=      ("planned period for cycling in seconds (default: %(default)s)", "positional", None, float),
    min_duration=("minimal real 'action' duration in seconds (default:%(default)s)", "positional", None, float),
    max_duration=("maximal 'real action' duration in seconds (default:%(default)s)", "positional", None, float),
)    
def main(period = 1.0, min_duration = 0.1, max_duration = 2.0):
    """Tries to start some randomly long action in regular periods"""
    print """call with -h for help.
    period      : %(period)f
    min_duration: %(min_duration)f
    max_duration: %(max_duration)f""" % locals()
    try:
        last_time = now = time.time()
        header = (   "%5s|"          +"%14s|"    +"%14s|"           +"%8s|"         +"%8s|"          +"%14s|") % ("cycle", "last_time", "now", "action", "real", "next_time")
        row =    "%(i) 5d|%(last_time)14.2f|%(now)14.2f|%(action_dur)8.3f|%(real_dur)8.3f|%(next_time)14.2f|"
        print header
        action_dur = real_dur = 0.0
        for i, next_time in izip(count(), sleep_gen(period)):
            #we care about starting the action on time, not ending
            now = time.time() #sleep_gen just tried to keep the period on schedule
            real_dur = now - last_time
            print row % locals()
            last_time = now
            #performing the "action"
            action_dur = random.random() * (max_duration - min_duration) + min_duration
            time.sleep(action_dur)
    except KeyboardInterrupt:
        print "...cancelled."

if __name__ == "__main__":
    plac.call(main)

从命令行调用它:

$ python cycle.py
call with -h for help.
    period      : 1.000000
    min_duration: 0.100000
    max_duration: 2.000000
cycle|     last_time|           now|  action|    real|     next_time|
    0| 1337368558.55| 1337368558.55|   0.000|   0.002| 1337368559.55|
    1| 1337368558.55| 1337368559.59|   1.042|   1.042| 1337368560.59|
    2| 1337368559.59| 1337368561.32|   1.722|   1.723| 1337368562.32|
    3| 1337368561.32| 1337368562.32|   0.686|   1.000| 1337368563.32|
    4| 1337368562.32| 1337368563.32|   0.592|   1.000| 1337368564.32|
    5| 1337368563.32| 1337368564.75|   1.439|   1.439| 1337368565.75|
    6| 1337368564.75| 1337368566.08|   1.323|   1.323| 1337368567.08|
    7| 1337368566.08| 1337368567.08|   0.494|   0.999| 1337368568.08|
    8| 1337368567.08| 1337368568.20|   1.120|   1.121| 1337368569.20|
    9| 1337368568.20| 1337368569.20|   0.572|   1.000| 1337368570.20|
   10| 1337368569.20| 1337368570.20|   0.586|   1.000| 1337368571.20|
   11| 1337368570.20| 1337368571.20|   0.309|   0.999| 1337368572.20|
   12| 1337368571.20| 1337368572.20|   0.290|   1.000| 1337368573.20|
   13| 1337368572.20| 1337368573.25|   1.052|   1.053| 1337368574.25|
   14| 1337368573.25| 1337368574.25|   0.737|   1.000| 1337368575.25|
   15| 1337368574.25| 1337368575.83|   1.579|   1.579| 1337368576.83|
...cancelled.

将您的问题与我的答案进行比较:

  • 发电机:是的,是
  • 输入开始时间:我仅使用当前时间(可能是人们经常需要的时间)
  • 输入结束时间:那一刻停止呼叫发电机。 或修改生成器以仅循环一定数量的循环或在特定时间结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM