Python:在类的with语句中重复命令块的内容

问题描述

很抱歉重复一个问题。不幸的是,我找不到适合我的答案。 我想编写一个类,以在ipython中以%timeit的方式计算代码的执行时间(平均值和执行时间的均方根值)。 为此,我在with语句中使用了这段代码https://stackoverflow.com/a/28218696/5328802

这是测试:

from TimingManager import TimingManager
import numpy as np

N = 10000

def myfunction1():
    l = [i**2 for i in range(N)]
def myfunction2():
    l = np.arange(N)**2

print("List test")
with TimingManager(fun=yourfunction1,repeat=10) as t:
    t.start()

print("Array test")
with TimingManager(fun=yourfunction2,repeat=10) as t:
    t.start()

这是我对TimingManager类(文件TimingManager.py)的实现:

import timeit
import statistics

class TimingManager():
    """Context Manager used with the statement 'with' to time some execution.

    Example:

    from TimingManager import TimingManager
    with TimingManager(fun=yourfunction,repeat=10) as t:
       t.start()
    """
    clock = timeit.default_timer

    def __init__(self,fun,repeat=10):
        self.repeat = repeat
        self.time_table = []
        self.run = fun

    def start(self):
        for i in range(self.repeat):
            self.timestart = self.clock()
            self.run()
            self.time_table.append(self.clock() - self.timestart)

    def __enter__(self):
        """ action on start """
        self.timestart = self.clock()

        return self

    def __exit__(self,exc_type,exc_val,exc_tb):
        """ action on exit """
        self.print_process_stat()

        return False

    def print_process_stat(self):
        tc = statistics.mean(self.time_table)
        dt = statistics.pstdev(self.time_table)
        print("Execution time is %s ± %s"%(time_conversion(tc),time_conversion(dt)))

def time_conversion(t):
    if t < 1e-9:
        return "%4.3g ps" % (t/1e-12)
    elif t < 1e-6:
        return "%4.3g ms" % (t/1e-9)
    elif t < 1e-3:
        return "%4.3g μs" % (t/1e-6)
    elif t < 1:
        return "%4.3g ms" % (t/1e-3)
    elif t < 60:
        return "%4.3g s" % (t)
    elif t < 3600:
        return "%2d min %2d s" % (t//60,t%60)
    elif t < 24*3600:
        return "%2d h %2d min" % (t//3600,(t/60)%60)
    else:
        return "%2d d %2d h" % (t//(24*3600),(t/60)%60)

它为我提供了所需时间的统计信息。但是我认为这并不优雅。所以我的问题是,是否可以以一种更优雅的方式(无需定义myfunction)来实现此过程,即在with语句之后访问该块(也许使用内容管理器)以重复它放在TimingManager类中?最后要使用这样的东西:

with TimingManager(repeat=10):
    Statemet1
    Statemet2
    ..

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)