覆盖另一个库中函数的返回值

时间:2017-03-16 15:23:02

标签: python progress-bar

我正在使用一个在循环中调用函数some_func的库。

def main():
    xs = []
    for x in y:
        xs.append(some_func(x))
    return xs

def some_func(x):
    return some_data

我想拦截some_func函数的响应并用我的值覆盖它。例如:

def some_func(x):
    return my_func(some_data)

这样做的目的是让我可以运行一些进度挂钩来跟踪完成这个过程所需的时间。

如何在不修改原始库源代码的情况下执行此操作?

2 个答案:

答案 0 :(得分:1)

您可以使用装饰器,但不是将其应用于@,而是直接包装目标函数。像这样:

>>> import math
>>> def wrap_function(func):
...     def wrapper(x):
...         print('Called {0} with {1}'.format(func.__name__, x))
...         result = func(x)
...         print('Returned value is {0!r}'.format(result))
...         return result
...     return wrapper
... 
>>> math.sin = wrap_function(math.sin)
>>> r = math.sin(1.1337)
Called sin with 1.1337
Returned value is 0.905984636371863
>>> r
0.905984636371863

鉴于您现在可以在通话之前/之后进行操作,您可以实施时间测量等等。

答案 1 :(得分:0)

如果我理解正确的话,你应该研究装饰师。以下是Andreas Jung的摘录。这允许您在所选的任何函数上添加@timeit装饰器。

import time                                                

def timeit(method):

    def timed(*args, **kw):
        ts = time.time()
        result = method(*args, **kw)
        te = time.time()

        print '%r (%r, %r) %2.2f sec' % \
              (method.__name__, args, kw, te-ts)
        return result

    return timed

class Foo(object):

    @timeit
    def foo(self, a=2, b=3):
        time.sleep(0.2)

@timeit
def f1():
    time.sleep(1)
    print 'f1'

@timeit
def f2(a):
    time.sleep(2)
    print 'f2',a

@timeit
def f3(a, *args, **kw):
    time.sleep(0.3)
    print 'f3', args, kw

f1()
f2(42)
f3(42, 43, foo=2)
Foo().foo()