关于python 2.7:在包装器中的模块中包装所有函数

Wrap all functions in a module in a wrapper

我有一个模块mymod,它定义了一打具有相同签名的函数

1
2
3
def myfun1 (a,b,c):
    ...
    return d

我想像这样追踪所有这些函数:

1
2
3
4
5
6
7
8
9
10
11
12
def traced (f):
    def wrapped (a,b,c):
        print">>>%s(%d)" % (f.__name__, (a+b)/c)
        d = f(a,b,c)
        print"<<<%s(%g)" % (f.__name__, 1/d)
        return d
    return wrap

@traced
def myfun1 (a,b,c):
    ...
    return d

(这里,(a+b)/c1/d代表更复杂的东西)。

除了在函数定义之前添加@traced之外,还有更优雅的方法来完成这个任务吗?

另外,5年前也有人问过类似的问题。我想知道是否有新的答案。


通过浏览globals()dict,可以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def myfun1 (a,b,c):
    return 1.+a+b+c

def myfun2 (a,b,c):
    return 1.+a+b-c

def traced (f):
    def wrapped (a,b,c):
        print">>>%s(%d)" % (f.__name__, (a+b)/c)
        d = f(a,b,c)
        print"<<<%s(%g)" % (f.__name__, 1/d)
        return d
    return wrapped

print 'myfun1(1,2,3): ', myfun1(1,2,3)
print 'myfun2(1,2,3): ', myfun2(1,2,3)

import types
for x in globals().copy(): # copy() is mandatory because globals() is being updated
    if x == 'traced' or x.startswith('__'): # Ignore trace function and private ones
        continue
    if isinstance(globals()[x], types.FunctionType):
        print"Found function:", x
        globals()[x] = traced(globals()[x])


print 'myfun1(1,2,3): ', myfun1(1,2,3)
print 'myfun2(1,2,3): ', myfun2(1,2,3)

结果:

1
2
3
4
5
6
7
8
9
10
myfun1(1,2,3):  7.0
myfun2(1,2,3):  1.0
Found function: myfun1
Found function: myfun2
myfun1(1,2,3):  >>>myfun1(1)
<<<myfun1(0.142857)
7.0
myfun2(1,2,3):  >>>myfun2(1)
<<<myfun2(1)
1.0