inspect.getargvalues()抛出异常" AttributeError:' tuple'对象没有属性' f_code'"

时间:2015-04-29 05:43:16

标签: python introspection

我尝试使用Python的inspect模块(在Python 2中)来显示有关调用当前函数的函数的信息,包括其参数。

这是一个简单的测试程序:

import inspect

def caller_args():
    frame = inspect.currentframe()
    outer_frames = inspect.getouterframes(frame)
    caller_frame = outer_frames[1]
    return inspect.getargvalues(caller_frame)

def fun_a(arg1):
    print caller_args()

def fun_b():
    fun_a('foo')

if __name__ == '__main__':
    fun_b()

当我运行它时会发生这种情况:

$ python getargvalues_test.py
Traceback (most recent call last):
  File "getargvalues_test.py", line 16, in <module>
    fun_b()
  File "getargvalues_test.py", line 13, in fun_b
    fun_a('foo')
  File "getargvalues_test.py", line 10, in fun_a
    print caller_args()
  File "getargvalues_test.py", line 7, in caller_args
    return inspect.getargvalues(caller_frame)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 829, in getargvalues
    args, varargs, varkw = getargs(frame.f_code)
AttributeError: 'tuple' object has no attribute 'f_code'

我用google搜索了AttributeError异常,但没有运气。我做错了什么?

(我已经发现了这个问题,所以我在这里回答这个问题,所以今后遇到这个问题的人都会在这里找到答案。)

2 个答案:

答案 0 :(得分:4)

This similar question帮我发现了问题。

inspect模块的Python documentation提及“帧记录”和“帧对象”,并解释了差异。

  • inspect.currentframe()会返回一个对象框架,但
  • inspect.getouterframes()会返回记录 的框架列表。

上面代码中的错误不是从调用函数的帧记录中提取帧对象,而是传递inspect.getouterframes()帧记录而不是帧对象。 (注意inspect.getouterframes()不检查其参数是否为框架对象。)

以下是caller_args()的固定定义(将更改分配给caller_frame):

def caller_args():
    frame = inspect.currentframe()
    outer_frames = inspect.getouterframes(frame)
    caller_frame = outer_frames[1][0]
    return inspect.getargvalues(caller_frame)

根据需要运行:

$ python getargvalues_test_fixed.py
ArgInfo(args=['arg1'], varargs=None, keywords=None, locals={'arg1': 'foo'})

答案 1 :(得分:0)

错误原因

  

AttributeError:'tuple'对象没有属性'f_code'

在您的函数中

  

def caller_args()

是caller_frame是一个数组,你需要将item [1] [0]作为

的参数
  

inspect.getargvalues(...)

这有效:

currframe = inspect.currentframe()
callerframe = inspect.getouterframes(currframe, 2)
inspect.getargvalues(callerframe[1][0])

此外,getargvalues函数返回4个值。在这种情况下,前三个不重要,第四个包含JSON,如调用者参数的格式键/值列表

 _,_,_,values = inspect.getargvalues(callerframe[1][0])
 for i in values:
     argsstring += str(i) + ' : ' + str(values[i])

我的测试看起来像这样:

import inspect

def log(text):
    currframe = inspect.currentframe()
    callerframe = inspect.getouterframes(currframe, 2)
    _,_,_,values = inspect.getargvalues(callerframe[1][0])
    argsstring = ''
    for i in values:
        argsstring += str(i) + ' : ' + str(values[i])
    print('name of file : ' + callerframe[1][1])
    print('name of function : ' + callerframe[1][3])
    print('line number : ' + str(callerframe[1][2]))
    print('caller function arguments : ' + argsstring)

def doTest(text):
    log(text) 

doTest('this is a test')