在python中的sys.settrace中打印函数参数

时间:2015-09-16 11:26:38

标签: python

我如何检查sys.settrace调用中函数参数的值?似乎我有可能输出除了参数之外的所有东西(行,文件名,堆栈跟踪,返回值等)。是否有一种解决方法可以让我跟踪函数参数值?




2 个答案:

答案 0 :(得分:11)

您可以使用代码对象和框架对象的组合。

请参阅Python Data-Model Reference中的相关说明。

import sys

def fn(frame, msg, arg):
    if msg != 'call': return
    # Filter as appropriate
    if frame.f_code.co_filename.startswith("/usr"): return
    print("Called", frame.f_code.co_name)
    for i in range(frame.f_code.co_argcount):
        name = frame.f_code.co_varnames[i]
        print("    Argument", name, "is", frame.f_locals[name])

sys.settrace(fn)

def hai(a, b, c):
    print(a, b, c)

hai("Hallo", "Welt", "!")

要意识到的关键是

  1. 我们可以将框架中的所有局部变量都看作f_locals
  2. 我们可以从f_code.co_varnames
  3. 中提取参数列表中的变量名称

答案 1 :(得分:0)

我将Marcs答案变成了可用于检查其他脚本的脚本:

print_func_calls.py:

#!/usr/bin/env python

import sys

# opt-out file names which start with one of these prefixes
FILENAME_FILTER = {"/usr", "<"}
# opt-in file names again which match one of these prefixes
FILENAME_UNFILTER = {"/lib/python/some-important-module"}
# opt-out function names
FN_NAME_FILTER = {"<module>", "__new__", "__setattr__", "<lambda>"}


def to_str(exp):
    """Turn an argument value into a string without dying on exceptions"""
    try:
        return repr(exp)[:100]
    except Exception as exc:
        return "n/a"


def fn(frame, msg, arg):
    if msg != 'call':
        return

    filename, fn_name = frame.f_code.co_filename, frame.f_code.co_name

    if (not all(not filename.startswith(p) for p in FILENAME_FILTER) and 
            all(not filename.startswith(p) for p in FILENAME_UNFILTER) or
            fn_name in FN_NAME_FILTER):
        return

    argstr = ", ".join("%s=%s" % (
            frame.f_code.co_varnames[i], to_str(frame.f_locals[frame.f_code.co_varnames[i]]))
            for i in range(frame.f_code.co_argcount))

    print(">>> %s::\033[37m%s\033[0m(%s)" % (filename, fn_name, argstr))


sys.settrace(fn)

sys.argv = sys.argv[1:]
exec(open(sys.argv[0]).read())

像这样使用它:

print_func_calls.py my-script.py arg1..argN
相关问题