-1

我正在编写一个时钟对象,该对象可用于对程序中的事件进行计时,然后报告其各种时间,例如它的运行时间、开始和停止时间等。我也写了一个时钟对象,它跟踪整个程序中使用的各种时钟实例,并在打印输出中总结所有时钟的详细信息。

我已经让时钟对象工作了,但是我很难看到如何在我当前的实现中跟踪它的开始时间。这是因为它重置了开始时间的内部记录,以便正确地将时间添加到其内部累加器。我将不胜感激有关使事情正常工作的任何指导。

代码如下。我已经在时钟对象上包含了代码等等,以便清楚我想要实现的目标,并且建议的解决方案不会删除关键功能(我已经尽可能地减少了)。

from __future__ import division
import os
import time
import uuid as uuid
import datetime

def main():

    global clocks
    clocks = Clocks()

    print("create clock alpha")
    alpha = Clock(name = "alpha")
    print("clock alpha start time: {time}".format(time = alpha.startTime()))
    print("sleep 2 seconds")
    time.sleep(2)
    print("clock alpha current time (s): {time}".format(time = alpha.time()))

    print

    print("create clock beta")
    beta = Clock(name = "beta")
    print("clock beta start time: {time}".format(time = beta.startTime()))
    print("sleep 2 seconds")
    time.sleep(2)
    print("clock beta current time (s): {time}".format(time = beta.time()))
    print("stop clock beta")
    beta.stop()
    print("clock beta start time: {time}".format(time = beta.startTime()))
    print("clock beta stop time: {time}".format(time = beta.stopTime()))
    print("sleep 2 seconds")
    time.sleep(2)
    print("clock beta current time (s): {time}".format(time = beta.time()))

    print

    print("create two gamma clocks")
    gamma1 = Clock(name = "gamma")
    gamma1 = Clock(name = "gamma")
    print("sleep 2 seconds")
    time.sleep(2)

    print

    print("create two unnamed clocks")
    delta = Clock()
    epsilon = Clock()
    print("sleep 2 seconds")
    time.sleep(2)

    print

    print("clocks full printout:\n")
    clocks.printout(style = "full")

    print("clocks statistics printout:\n")
    clocks.printout()

class Clock(object):

    def __init__(
        self,
        name             = None,
        start            = True
        ):
        self._name       = name
        self._start      = start # Boolean start clock on instantiation
        self._updateTime = None # internal
        # If no name is specified, generate a unique one.
        if self._name is None:
            self._name = UID()
        # If a global clock list is detected, add a clock instance to it.
        if "clocks" in globals():
            clocks.add(self)
        self.reset()
        if self._start:
            self.start()

    def start(self):
        self._startTime  = datetime.datetime.utcnow()

    def stop(self):
        self._updateTime = None
        self._startTime  = None
        self._stopTime   = datetime.datetime.utcnow()

    # Update the clock accumulator.
    def update(self):
        if self._updateTime:        
            self.accumulator += (
                datetime.datetime.utcnow() - self._updateTime
            )
        else:
            self.accumulator += (
                datetime.datetime.utcnow() - self._startTime
            )
        self._updateTime  = datetime.datetime.utcnow()

    def reset(self):
        self.accumulator  = datetime.timedelta(0)
        self._startTime   = None

    # If the clock has a start time, add the difference between now and the
    # start time to the accumulator and return the accumulation. If the clock
    # does not have a start time, return the accumulation.
    def elapsed(self):
        if self._startTime:
            self.update()
        return(self.accumulator)

    def name(
        self
        ):
        return(self._name)

    def time(self):
        return(self.elapsed().total_seconds())

    def startTime(self):
        if self._startTime:
            return(style_datetime_object(datetimeObject = self._startTime))
        else:
            return("none")

    def stopTime(self):
        if self._stopTime:
            return(style_datetime_object(datetimeObject = self._stopTime))
        else:
            return("none")

class Clocks(object):

    def __init__(
        self
        ):
        self._listOfClocks = []
        self._defaultReportStyle = "statistics"

    def add(
        self,
        clock
        ):
        self._listOfClocks.append(clock)

    def report(
        self,
        style = None
        ):
        if style is None:
            style = self._defaultReportStyle
        if self._listOfClocks != []:
            if style == "statistics":
                # Create a dictionary of clock types with corresponding lists of
                # times for all instances.
                dictionaryOfClockTypes = {}
                # Get the names of all clocks and add them to the dictionary.
                for clock in self._listOfClocks:
                    dictionaryOfClockTypes[clock.name()] = []
                # Record the values of all clocks for their respective names in
                # the dictionary.
                for clock in self._listOfClocks:
                    dictionaryOfClockTypes[clock.name()].append(clock.time())
                # Create a report, calculating the average value for each clock
                # type.
                string = "clock type".ljust(39) + "mean time (s)"
                for name, values in dictionaryOfClockTypes.iteritems():
                    string += "\n" +\
                              str(name).ljust(39) + str(sum(values)/len(values))
                string += "\n"
            elif style == "full":
                # Create a report, listing the values of all clocks.
                string = "clock".ljust(39) + "time (s)"
                for clock in self._listOfClocks:
                    string += "\n" +\
                              str(clock.name()).ljust(39) + str(clock.time())
                string += "\n"
        else:
            string = "no clocks"
        return(string)

    def printout(
        self,
        style = None
        ):
        if style is None:
            style = self._defaultReportStyle
        print(self.report(style = style))

def UID():
    return(str(uuid.uuid4()))

def style_datetime_object(
    datetimeObject = None,
    style = "YYYY-MM-DDTHHMMSS"
    ):
    # filename safe
    if style == "YYYY-MM-DDTHHMMSSZ":
        return(datetimeObject.strftime('%Y-%m-%dT%H%M%SZ'))
    # microseconds
    elif style == "YYYY-MM-DDTHHMMSSMMMMMMZ":
        return(datetimeObject.strftime('%Y-%m-%dT%H%M%S%fZ'))
    # elegant
    elif style == "YYYY-MM-DD HH:MM:SS UTC":
        return(datetimeObject.strftime('%Y-%m-%d %H:%M:%SZ'))
    # UNIX time in seconds with second fraction
    elif style == "UNIX time S.SSSSSS":
        return(
            (datetimeObject -\
            datetime.datetime.utcfromtimestamp(0)).total_seconds()
        )
    # UNIX time in seconds rounded
    elif style == "UNIX time S":
        return(
            int((datetimeObject -\
            datetime.datetime.utcfromtimestamp(0)).total_seconds())
        )
    # filename safe
    else:
        return(datetimeObject.strftime('%Y-%m-%dT%H%M%SZ'))

if __name__ == '__main__':
    main()

运行时的示例打印输出如下:

create clock alpha
clock alpha start time: 2014-12-28T060943Z
sleep 2 seconds
clock alpha current time (s): 2.001554

create clock beta
clock beta start time: 2014-12-28T060945Z
sleep 2 seconds
clock beta current time (s): 2.001759
stop clock beta
clock beta start time: none
clock beta stop time: 2014-12-28T060947Z
sleep 2 seconds
clock beta current time (s): 2.001759

create two gamma clocks
sleep 2 seconds

create two unnamed clocks
sleep 2 seconds

clocks full printout:

clock                                  time (s)
alpha                                  10.01031
beta                                   2.001759
gamma                                  4.004501
gamma                                  4.004482
fdce3cc9-2178-4a72-99c5-22c77ad9cbbc   2.002209
d90d9263-ffaf-44f1-ace9-f8ddf5c78d87   2.002156

clocks statistics printout:

clock type                             mean time (s)
alpha                                  10.010368
beta                                   2.001759
d90d9263-ffaf-44f1-ace9-f8ddf5c78d87   2.00219
gamma                                  4.004532
fdce3cc9-2178-4a72-99c5-22c77ad9cbbc   2.002244

说明问题的关键是clock beta start time: none. 时钟“测试版”应该2014-12-28T060945Z在那个时候报告。

4

1 回答 1

1

您的问题(我想,我没有通读您的全部代码)在开头的这个块中:

print("create clock beta")
beta = Clock(name = "beta")
print("clock beta start time: {time}".format(time = beta.startTime()))
print("sleep 2 seconds")
time.sleep(2)
print("clock beta current time (s): {time}".format(time = beta.time()))
print("stop clock beta")
beta.stop()
print("clock beta start time: {time}".format(time = beta.stopTime())) # right here
print("clock beta stop time: {time}".format(time = beta.stopTime()))
print("sleep 2 seconds")
time.sleep(2)
print("clock beta current time (s): {time}".format(time = beta.time()))

您正在打印"clock beta start time:",但您正在将结果传递beta.stopTime()给字符串格式化程序,就像您在下一行中所做的那样。另外,既然你打电话给beta.stop(),我不确定你期望最后一行做什么,因为理论上beta是 2 秒前停止的。

于 2014-12-28T06:39:41.470 回答