微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Python中使用__code__为包装函数获取firstlineno?

如何解决如何在Python中使用__code__为包装函数获取firstlineno?

我想以静态方式获取函数的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

run.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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。