我可以叫回溯过去的函数的参数?怎么样?

我想为标准误差捕手使可读代码,还提供详细信息给用户。

在下面的例子中我想GET_PARAMS返回我的供给os.chown参数的元组。检查由亚历克斯·马尔泰利劝inspect模块,我无法找到。

def catch_errors(fn):
    def decorator(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except (IOError, OSError):
            msg = sys.exc_info()[2].tb_frame.f_locals['error_message']
            quit(msg.format(SEQUENCE_OF_PARAMETERS_OF_THE_LAST_FUNCTION_CALLED)\
            + '\nError #{0[0]}: {0[1]}'.format(sys.exc_info()[1].args), 1)
    return decorator

@catch_errors
def do_your_job():
    error_message = 'Can\'t change folder ownership \'{0}\' (uid:{1}, gid:{2})'
    os.chown('/root', 1000, 1000) # note that params aren't named vars.

if __name == '__main__' and os.getenv('USERNAME') != 'root':
    do_your_job()

(感谢用于装饰吉姆罗伯特

有帮助吗?

解决方案

通过使用装饰为你想达到什么样的问题是,异常处理程序得到帧do_your_job()s,不os.listdir()s,os.makedirs()s或os.chown()s。所以你就可以打印出的信息是do_your_job()的参数。为了得到该行为我想你打算,你就必须来装点你正在调用库函数。

其他提示

有关这样的检查任务,总是认为第一模块 inspect <的/ A>在标准库。在这里, inspect.getargvalues 为您提供的参数值给出一个框架,并 inspect.getinnerframes 为您提供了框架从回溯对象的兴趣。

下面是和这样的功能的例子一些问题,你不能得到解决:

import sys

def get_params(tb):
    while tb.tb_next:
        tb = tb.tb_next
    frame = tb.tb_frame
    code = frame.f_code
    argcount = code.co_argcount
    if code.co_flags & 4: # *args
        argcount += 1
    if code.co_flags & 8: # **kwargs
        argcount += 1
    names = code.co_varnames[:argcount]
    params = {}
    for name in names:
        params[name] = frame.f_locals.get(name, '<deleted>')
    return params


def f(a, b=2, c=3, *d, **e):
    del c
    c = 4
    e['g'] = 6
    assert False

try:
    f(1, f=5)
except:
    print get_params(sys.exc_info()[2])

的输出是:

{'a': 1, 'c': 4, 'b': 2, 'e': {'g': 6, 'f': 5}, 'd': ()}

我没用过inspect.getinnerframes()展现另一种方式来获得所需的框架。虽然简化了一点,它也做到这一点并不需要你,同时相对缓慢一些额外的工作(inspect.getinnerframes()读取源文件中追踪每一个模块,这是不是一个调试呼叫重要,但可能会在其他情况下的一个问题)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top