从另一个库覆盖函数的 return 值

Override a function's return value from another library

我正在使用一个循环调用函数 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)

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

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

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

>>> 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

鉴于您现在可以在调用之前/之后执行操作,您可以实现时间测量等。

如果我对您的理解正确,那么您应该研究装饰器。这是来自 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()