如何在Python模块中获取函数的行号(有/没有装饰器)?
我想获取一个Python函数在源代码中的行号。
在运行时,我手里有模块、类和方法的对象。
我查看了一下inspect模块。
inspect.getsourcelines(object)
这个模块的结果中也会给出行号。
不过我发现,对于带有装饰器的方法,inspect函数返回的行号指向的是装饰器的源代码,而不是我想要的函数的源代码。
有没有什么办法可以解决这个问题?
(我知道解释器在运行时会把函数包裹在装饰器里面,但我可能理解错了。)
2 个回答
5
wrapt模块解决了这个问题,它让你可以写装饰器,同时保留一些重要的信息,这样你就能找到函数的来源,还能进行其他的检查。可以把它看作是对functools.wraps
的一个升级版。
6
在一般情况下,没有简单的解决办法。
装饰器是一种函数,它接受一个函数作为输入,然后返回一个新的函数。通常,这个新函数会把原来的函数“包裹”起来,并执行装饰器设计的操作。
不过,文件和行号的信息并不在函数对象里,你不能通过把这些信息从被包裹的函数复制到包装函数来“修复”它们。这些数据实际上包含在函数的 code
对象中(可以通过 .func_code
获取),并且这些信息在你要创建的所有闭包中是共享的。
>>> def bar(x):
... def foo():
... return x
... return foo
...
>>> f1 = bar(1)
>>> f2 = bar(2)
>>> f1()
1
>>> f2()
2
>>> f1.func_code is f2.func_code
True
>>>