如何提取python代码文件中使用的函数? [英] How to extract functions used in a python code file?

查看:25
本文介绍了如何提取python代码文件中使用的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个代码文件中使用的所有函数的列表.例如,如果我们在名为add_random.py"的文件中有以下代码

`

将 numpy 导入为 np从 numpy 导入 linalg定义 foo():打印 np.random.rand(4) + np.random.randn(4)打印 linalg.norm(np.random.rand(4))

`

我想提取以下列表:<代码>[numpy.random.rand, np.random.randn, np.linalg.norm, np.random.rand]

该列表包含代码中使用的函数及其实际名称,格式为module.submodule.function".有没有用 python 语言构建的东西可以帮助我做到这一点?

解决方案

您可以使用以下命令提取所有调用表达式:

导入 ast类 CallCollector(ast.NodeVisitor):def __init__(self):self.calls = []self.current = 无def visit_Call(self, node):# new call,跟踪函数表达式self.current = ''self.visit(node.func)self.calls.append(self.current)self.current = 无def generic_visit(self, node):如果 self.current 不是 None:打印警告:不支持函数表达式中的 {} 节点".format(node.__class__.__name__)super(CallCollector, self).generic_visit(node)# 记录func表达式defvisit_Name(self, node):如果 self.current 是 None:返回self.current += node.iddef visit_Attribute(self, node):如果 self.current 是 None:self.generic_visit(节点)self.visit(node.value)self.current += '.'+ node.attr

将其与 ast 解析树一起使用:

tree = ast.parse(yoursource)cc = CallCollector()cc.visit(树)打印 cc.calls

演示:

<预><代码>>>>tree = ast.parse('''...定义 foo():... 打印 np.random.rand(4) + np.random.randn(4)... 打印 linalg.norm(np.random.rand(4))... ''')>>>cc = CallCollector()>>>cc.visit(树)>>>抄送['np.random.rand', 'np.random.randn', 'linalg.norm']

上面的walker只处理名字和属性;如果您需要更复杂的表达式支持,则必须对其进行扩展.

请注意,像这样收集姓名并非易事.不会处理任何间接.你可以在你的函数代码中建立一个字典来调用和动态换出函数对象,像上面这样的静态分析将无法跟踪它.

I would like to create a list of all the functions used in a code file. For example if we have following code in a file named 'add_random.py'

`

import numpy as np
from numpy import linalg

def foo():
    print np.random.rand(4) + np.random.randn(4)
    print linalg.norm(np.random.rand(4))

`

I would like to extract the following list: [numpy.random.rand, np.random.randn, np.linalg.norm, np.random.rand]

The list contains the functions used in the code with their actual name in the form of 'module.submodule.function'. Is there something built in python language that can help me do this?

解决方案

You can extract all call expressions with:

import ast

class CallCollector(ast.NodeVisitor):
    def __init__(self):
        self.calls = []
        self.current = None

    def visit_Call(self, node):
        # new call, trace the function expression
        self.current = ''
        self.visit(node.func)
        self.calls.append(self.current)
        self.current = None

    def generic_visit(self, node):
        if self.current is not None:
            print "warning: {} node in function expression not supported".format(
                node.__class__.__name__)
        super(CallCollector, self).generic_visit(node)

    # record the func expression 
    def visit_Name(self, node):
        if self.current is None:
            return
        self.current += node.id

    def visit_Attribute(self, node):
        if self.current is None:
            self.generic_visit(node)
        self.visit(node.value)  
        self.current += '.' + node.attr

Use this with a ast parse tree:

tree = ast.parse(yoursource)
cc = CallCollector()
cc.visit(tree)
print cc.calls

Demo:

>>> tree = ast.parse('''
... def foo():
...     print np.random.rand(4) + np.random.randn(4)
...     print linalg.norm(np.random.rand(4))
... ''')
>>> cc = CallCollector()
>>> cc.visit(tree)
>>> cc.calls
['np.random.rand', 'np.random.randn', 'linalg.norm']

The above walker only handles names and attributes; if you need more complex expression support, you'll have to extend this.

Note that collecting names like this is not a trivial task. Any indirection would not be handled. You could build a dictionary in your code of functions to call and dynamically swap out function objects, and static analysis like the above won't be able to track it.

这篇关于如何提取python代码文件中使用的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆