Python 中多个代码行的函数包装器

Function wrapper for multiple code lines in Python

我想围绕一个函数包装一些代码(例如打印计时信息)并将该函数重用于多个代码块:

start = time.time()
print('Started adding numbers at {}'.format(start))
a = 1
b = 2
c = a + b
end = time.time()
print('Finished adding numbers in {} seconds'.format(end - start)')

是否可以将多行代码包装到一个包装函数中,而无需为每个代码块定义函数?一种方法是定义一个函数并使用装饰器,但我想避免对每个代码块都这样做:

@print_time
def foo():
    a = 1
    b = 2

    return a + b

你可以使用高阶函数来做到这一点,例如:

def inner():
    pass

def outer(inner):
    inner()

然后调用

outer(inner)

另类你怎么看这个:

您定义一个计时器 class,它按名称保存计时器,例如代码块的描述,并将所有打印和您喜欢的内容作为 stop_timer 函数中的选项。它仍然是两行代码,但我认为你不会得到那么少

import time as t

class myTimer:
    def __init__(self):
        self.timers = {}
    def start_timer(self, name):
        print('Started adding numbers at {}'.format(t.time()))
        self.timers[name] = t.time()
    def stop_timer(self,name):
        runtime = t.time() - self.timers[name]
        del(self.timers[name])
        print('Finished adding numbers in {} seconds'.format(runtime))
        return runtime

timer = myTimer()


timer.start_timer('First Timer')
timer.start_timer('Second Timer')
a = 1
t.sleep(1)
b = 2
timer.stop_timer('First Timer')
c = 3
t.sleep(2)
d = 4
timer.stop_timer('Second Timer')

Returns

Started adding numbers at 1606676633.8297324
Started adding numbers at 1606676633.8297324
Finished adding numbers in 1.0228865146636963 seconds
Finished adding numbers in 3.0250420570373535 seconds

您可以创建一个上下文管理器 class 并在 with 块中执行您的代码。这将实现紧凑且高度可重用的计时器功能。像这样:

import time

class TimeClass():
    def __init__(self):
        pass
    def __enter__(self):
        self.start = time.time()
    def __exit__(self, type, value, traceback):
        self.end = time.time()
        print('Finished executing in {} seconds'.format(self.end - self.start))

您可以像这样使用 class:

with TimeClass():
    # your code
    pass

查看 this link 了解更多详情。

另一种方法是使用 context managers

例如:

from contextlib import contextmanager

@contextmanager
def timer():
    start = time.time()
    print('Started adding numbers at {}'.format(start))
    yield
    end = time.time()
    print('Finished adding numbers in {} seconds'.format(end - start))


# Then call it like that
with timer():
    a = 1
    b = 2
    c = a + b