如何自动包装特定文件中的函数

时间:2016-09-14 10:07:04

标签: python python-2.7 python-3.x introspection

众所周知,有许多方法可以使用python标准库获取函数名称,这里有一个小例子:

import sys
import dis
import traceback


def get_name():
    stack = traceback.extract_stack()
    filename, codeline, funcName, text = stack[-2]
    return funcName


def foo1():
    print("Foo0 start")
    print("Inside-_getframe {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo1 end")


def foo2():
    print("Foo2 start")
    print("Inside {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo2 end")


def foo3():
    print("Foo3 start")
    print("Inside {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo3 end")

for f in [foo1, foo2, foo3]:
    print("Outside: {0}".format(f.__name__))
    f()
    print('-' * 80)

您可以使用tracebacksys._getframedis,也许还有很多选项......到目前为止,这样的内省很棒,python非常棒。

现在,就是这样,我想知道如何自动包装函数(在文件级别)来打印它的名称,并测量它们执行时的执行时间。例如,像这样:

def foo1():
    print("Foo0 processing")


def foo2():
    print("Foo2 processing")


def foo3():
    print("Foo3 processing")

wrap_function_from_this_file()

for f in [foo1, foo2, foo3]:
    f()
    print('-' * 80)

会打印出类似的内容:

foo1 started
Foo1 processing
foo1 finished, elapsed time=1ms
--------------------------------------------------------------------------------
foo2 started
Foo2 processing
foo2 finished, elapsed time=2ms
--------------------------------------------------------------------------------
foo3 started
Foo3 processing
foo3 finished, elapsed time=3ms
--------------------------------------------------------------------------------

正如您所看到的,这个想法是不会手动将任何包装器的每个函数添加到文件的函数中。 wrap_function_from_this_file 会自动内省执行文件的位置,它会修改包含它们的函数,在这种情况下,用一些代码打包函数打印它的名称和执行时间。

仅供记录,我不要求任何探查者。我想知道这是否可行以及如何做。

2 个答案:

答案 0 :(得分:1)

解决方案可以是使用ngFor来获取有关当前定义对象的信息。这是一个简单的包装函数,它用它们的包装版本替换给定全局数据中的函数:

globals()

可以像这样使用:

import types

def my_tiny_wrapper(glb):
    def wrp(f):
        # create a function which is not in 
        # local space of my_tiny_wrapper
        def _inner(*args, **kwargs):
            print('wrapped', f.__name__)
            return f(*args, **kwargs)
            print('end wrap', f.__name__)
        return _inner
    for f in [f for f in glb.values() if type(f) == types.FunctionType 
              and f.__name__ != 'my_tiny_wrapper']:
        print('WRAP FUNCTION', f.__name__) 
        glb[f.__name__] = wrp(f)

产生以下结果:

def peter(): pass
def pan(a): print('salat and onions')   
def g(a,b,c='A'): print(a,b,c)

# pass the current globals to the funcion
my_tiny_wrapper(globals())
g(4,b=2,c='D')  # test keyword arguments
peter()         # test no arguments
pan(4)          # single argument

答案 1 :(得分:0)

这是我正在寻找的解决方案:

mapper conf