从方法对象获取方法调用及其参数

dic

使用pythonsinspect模块,我隔离了一个方法对象,我现在需要逐步浏览该方法中的源代码以查找对某些其他方法的调用并获取其参数。

例如,假设在以下类中:

def my_method():
    print('hello')
    foobar('apple', 'pear', 6)
    print('world')
    foobar(1, 2, 3)
    return foobar('a', 'b')

我需要提取传递给的参数列表foobar()

[('apple', 'pear', 6), (1, 2, 3), ('a', 'b', None)]

可以假设所有参数都是硬编码的,不是动态的。

给定inspect包中的方法对象,如何检查所述方法中的方法调用?

尝试次数

  • 我已经尝试过使用正则表达式,inspect.getsourcelines(method)但是如果参数语法更改,则会中断。
  • 我已经使用pythonsast模块研究了抽象语法树,但是还没有任何解决方案。
  • 必须使用某种方法来完成此操作,inspect但是我仍然没有任何解决方案。
帕德拉克·坎宁安

这不是完美的,但应该是一个开始,我将稍后添加一个更好的实现:

from ast import parse, Call, walk
import importlib
import inspect

mod = "test"
mod = importlib.import_module(mod)
p = parse(inspect.getsource(mod))

from ast import literal_eval

vals = []
for node in p.body:
    if isinstance(node, FunctionDef) and node.name == "my_method":
        for node in walk(node):
            if isinstance(node,Call) and node.func.id == "foobar":
                vals.append([literal_eval(val) for val in node.args])

print(vals)

[['apple', 'pear', 6], [1, 2, 3], ['a', 'b']]

test.py看起来像:

def foobar(a=0, b=0, c=None):
    return a, b, c

def other_method(x,y,z):
    return  x,y,z

def my_method():
    print('hello')
    foobar('apple', 'pear', 6)
    print('world')
    foobar(1, 2, 3)
    for i in range(10):
        if i > 9:
            s = foobar(4, 5, 6)
            print(s)
    return foobar('a', 'b')


def my_method2():
    foobar('orange', 'tomatoe', 6)
    foobar(10, 20, 30)
    for i in range(10):
        if i > 9:
            foobar(40, 50, 60)
    other_method("foo","bar","foobar")
    return foobar('c', 'd')

如果您将两者混合使用,则需要以某种方式将通话更改print('world')foobar(a=1, b=2, c=3)

vals = []
for node in p.body:
    if isinstance(node, FunctionDef) and node.name == "my_method":
        for node in walk(node):
            if isinstance(node, Call) and node.func.id == "foobar":
                kws = node.keywords
                if kws:
                    print("Found keywords",[(kw.arg, literal_eval(kw.value)) for kw in kws])
                else:
                    print([literal_eval(val) for val in node.args])

输出:

[['apple', 'pear', 6], [], ['a', 'b'], [4, 5, 6]]
['apple', 'pear', 6]
('Found keywords', [('a', 1), ('b', 2), ('c', 3)])
['a', 'b']
[4, 5, 6]

使用ast.Nodevisitor查找所有Call对象将在所有函数中将所有调用返回到“ foobar”:

from ast import parse, NodeVisitor, literal_eval
import importlib
import inspect

mod = "test"
mod = importlib.import_module(mod)
p = parse(inspect.getsource(mod))


class FindCall(NodeVisitor):
    def __init__(self, *args):
        if len(args) < 1:
            raise ValueError("Must supply at least ine target function")
        self.result = {arg: []for arg in args}

    def visit_Call(self, node):
        if node.func.id in self.result:
            self.result[node.func.id].append(map(literal_eval, node.args))
        # visit the children
        self.generic_visit(node)



fc = FindCall("foobar")
fc.visit(p)
print(fc.result)

输出:

from pprint import pprint as pp
pp(fc.result)

{'foobar': [['apple', 'pear', 6],
            [1, 2, 3],
            [4, 5, 6],
            ['a', 'b'],
            ['orange', 'tomatoe', 6],
            [10, 20, 30],
            [40, 50, 60],
            ['c', 'd']],
 'other_method': [['foo', 'bar', 'foobar']]}

您可以再次添加搜索kwarg的功能,仅搜索特定功能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将对象及其方法之一作为参数传递

来自分类Dev

将对象及其方法之一作为参数传递

来自分类Dev

如何获取带注释的方法参数及其注释

来自分类Dev

Java:获取带有接口参数的方法及其实现

来自分类Dev

以对象数组为参数的调用方法

来自分类Dev

作为参数传递的对象的 JavaScript 调用方法

来自分类Dev

从另一个对象类方法调用一个对象及其方法

来自分类Dev

获取在 Python 中调用方法的对象

来自分类Dev

关于python对象及其方法

来自分类Dev

静态对象及其创建方法

来自分类Dev

有没有一种方法可以使用对象及其非空参数列表调用运算符生成std :: thread?

来自分类Dev

如何从对象的父类的方法内部获取对象的调用实例?

来自分类Dev

php:如何使用名称作为变量调用对象及其方法

来自分类Dev

如何在C#中获取当前方法的名称及其参数(名称和值)

来自分类Dev

如何检查不仅使用特定参数调用模拟对象的方法?

来自分类Dev

从Javassist调用以对象为参数的方法

来自分类Dev

根据调用方法时的修改类对象参数

来自分类Dev

NxBRE规则引擎,使用传递对象作为参数的调用方法

来自分类Dev

Spark scala中基于json对象参数的调用方法?

来自分类Dev

Testng:在侦听器中获取调用的方法参数信息

来自分类Dev

从Clang Match回调获取方法调用的参数

来自分类Dev

从AOP调用类获取方法名称和参数

来自分类Dev

如何使用获取AssertionError的线程调用不带参数的方法

来自分类Dev

在使用 beginInvoke 调用的异步方法中获取参数值

来自分类Dev

带参数的调用方法

来自分类Dev

作为方法调用参数

来自分类Dev

调用方法作为参数

来自分类Dev

参数更改的调用方法

来自分类Dev

参数方法调用Sencha

Related 相关文章

  1. 1

    将对象及其方法之一作为参数传递

  2. 2

    将对象及其方法之一作为参数传递

  3. 3

    如何获取带注释的方法参数及其注释

  4. 4

    Java:获取带有接口参数的方法及其实现

  5. 5

    以对象数组为参数的调用方法

  6. 6

    作为参数传递的对象的 JavaScript 调用方法

  7. 7

    从另一个对象类方法调用一个对象及其方法

  8. 8

    获取在 Python 中调用方法的对象

  9. 9

    关于python对象及其方法

  10. 10

    静态对象及其创建方法

  11. 11

    有没有一种方法可以使用对象及其非空参数列表调用运算符生成std :: thread?

  12. 12

    如何从对象的父类的方法内部获取对象的调用实例?

  13. 13

    php:如何使用名称作为变量调用对象及其方法

  14. 14

    如何在C#中获取当前方法的名称及其参数(名称和值)

  15. 15

    如何检查不仅使用特定参数调用模拟对象的方法?

  16. 16

    从Javassist调用以对象为参数的方法

  17. 17

    根据调用方法时的修改类对象参数

  18. 18

    NxBRE规则引擎,使用传递对象作为参数的调用方法

  19. 19

    Spark scala中基于json对象参数的调用方法?

  20. 20

    Testng:在侦听器中获取调用的方法参数信息

  21. 21

    从Clang Match回调获取方法调用的参数

  22. 22

    从AOP调用类获取方法名称和参数

  23. 23

    如何使用获取AssertionError的线程调用不带参数的方法

  24. 24

    在使用 beginInvoke 调用的异步方法中获取参数值

  25. 25

    带参数的调用方法

  26. 26

    作为方法调用参数

  27. 27

    调用方法作为参数

  28. 28

    参数更改的调用方法

  29. 29

    参数方法调用Sencha

热门标签

归档