python - 如何在 python 中使用 __code__ 获取包装函数的 firSTLineno?

标签 python inspect python-importlib

我想以静态方式获取函数的 co_firSTLineno,展开的函数是可以的, 但是如果一个方法被包装了,我只能得到包装函数所在的lineno。

md.py

import functools

def run(func):
    @functools.wraps(func)
    def warper(*args, **kwargs):
        res = func()
        return res
    return warper

def func_unwrapper():
    pass

@run
def func_with_wrapper():
    pass

运行.py

from importlib import util as module_util
import inspect

def load_moudle_by_path(path):
    foo = module_util.spec_from_file_location('md', path)
    md = module_util.module_from_spec(foo)
    foo.loader.exec_module(md)
    return md

def get_line():
    md = load_moudle_by_path('md.py')
    for name, o in inspect.getmembers(md):
        if inspect.isfunction(o):
            print('[{}]{}'.format(name, o.__code__.co_firstlineno))

get_line()


>>>
[func_unwrapper]10
[func_with_wrapper]4
[run]3

enter image description here

最佳答案

我明白您的期望,但该行为是预期的行为。

func_with_wrapper 确实在运行第 4 行的代码,第 13 行的代码(这可能是您希望/期待的)仅基于 func 参数传递(func_with_wrapper 参数)。

经过您自己的研究,找到 .__wrapped__functools 慷慨地添加了它,您自己无需添加类似的东西。

如果您更新,您的原始代码将有效:

def get_line():
    md = load_module_by_path('md.py')
    for name, o in inspect.getmembers(md):
        if inspect.isfunction(o):
            try:
                if o.__wrapped__:
                    print('decorated [{}]{}'.format(name, o.__wrapped__.__code__.co_firstlineno))
            except AttributeError:
                print('undecorated [{}]{}'.format(name, o.__code__.co_firstlineno))

输出:

undecorated [func_unwrapper]10
decorated [func_with_wrapper]13
undecorated [run]3

关于python - 如何在 python 中使用 __code__ 获取包装函数的 firSTLineno?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64335359/

相关文章:

python - python中的LDA使用sklearn

python - 堆栈计算器(后缀,Python)

python 获取传递函数的参数

python - 在Python包目录之外添加数据目录

python importlib 从错误的目录导入

Python:如何找到库属于哪个 pip 包?

python - 如何计算元素的值(value)?

Python 如何在 numpy 数组中查找第一个重复项

Python:检查异常引发的位置

java - "Inspect Element"Java UI 工具