如何在Python模块中获取函数的行号(有/没有装饰器)?

9 投票
2 回答
3348 浏览
提问于 2025-04-17 07:27

我想获取一个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
>>> 

撰写回答