我尝试使用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异常,但没有运气。我做错了什么?
(我已经发现了这个问题,所以我在这里回答这个问题,所以今后遇到这个问题的人都会在这里找到答案。)
答案 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')