开发者社区> 问答> 正文

解析与分析Python源码

解析与分析Python源码

展开
收起
哦哦喔 2020-04-17 16:28:08 947 0
2 条回答
写回答
取消 提交回答
  • 有点尴尬唉 你要寻找的东西已经被吃掉啦!
    
    import ast
    
    class CodeAnalyzer(ast.NodeVisitor):
        def __init__(self):
            self.loaded = set()
            self.stored = set()
            self.deleted = set()
    
        def visit_Name(self, node):
            if isinstance(node.ctx, ast.Load):
                self.loaded.add(node.id)
            elif isinstance(node.ctx, ast.Store):
                self.stored.add(node.id)
            elif isinstance(node.ctx, ast.Del):
                self.deleted.add(node.id)
    
    # Sample usage
    if __name__ == '__main__':
        # Some Python code
        code = '''
        for i in range(10):
            print(i)
        del i
        '''
    
        # Parse into an AST
        top = ast.parse(code, mode='exec')
    
        # Feed the AST to analyze name usage
        c = CodeAnalyzer()
        c.visit(top)
        print('Loaded:', c.loaded)
        print('Stored:', c.stored)
        print('Deleted:', c.deleted)
    
    如果你运行这个程序,你会得到下面这样的输出:
    
    Loaded: {'i', 'range', 'print'}
    Stored: {'i'}
    Deleted: {'i'}
    
    最后,AST可以通过 compile() 函数来编译并执行。例如:
    
    >>> exec(compile(top,'<stdin>', 'exec'))
    
    2020-04-17 17:34:21
    赞同 展开评论 打赏
  • 大部分程序员知道Python能够计算或执行字符串形式的源代码。例如:
    
    >>> x = 42
    >>> eval('2 + 3*4 + x')
    56
    >>> exec('for i in range(10): print(i)')
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>>
    尽管如此,ast 模块能被用来将Python源码编译成一个可被分析的抽象语法树(AST)。例如:
    
    >>> import ast
    >>> ex = ast.parse('2 + 3*4 + x', mode='eval')
    >>> ex
    <_ast.Expression object at 0x1007473d0>
    >>> ast.dump(ex)
    "Expression(body=BinOp(left=BinOp(left=Num(n=2), op=Add(),
    right=BinOp(left=Num(n=3), op=Mult(), right=Num(n=4))), op=Add(),
    right=Name(id='x', ctx=Load())))"
    
    >>> top = ast.parse('for i in range(10): print(i)', mode='exec')
    >>> top
    <_ast.Module object at 0x100747390>
    >>> ast.dump(top)
    "Module(body=[For(target=Name(id='i', ctx=Store()),
    iter=Call(func=Name(id='range', ctx=Load()), args=[Num(n=10)],
    keywords=[], starargs=None, kwargs=None),
    body=[Expr(value=Call(func=Name(id='print', ctx=Load()),
    args=[Name(id='i', ctx=Load())], keywords=[], starargs=None,
    kwargs=None))], orelse=[])])"
    >>>
    分析源码树需要你自己更多的学习,它是由一系列AST节点组成的。 分析这些节点最简单的方法就是定义一个访问者类,实现很多 visit_NodeName() 方法, NodeName() 匹配那些你感兴趣的节点。下面是这样一个类,记录了哪些名字被加载、存储和删除的信息。
    
    import ast
    
    class CodeAnalyzer(ast.NodeVisitor):
        def __init__(self):
            self.loaded = set()
            self.stored = set()
            self.deleted = set()
    
        def visit_Name(self, node):
            if isinstance(node.ctx, ast.Load):
                self.loaded.add(node.id)
            elif isinstance(node.ctx, ast.Store):
                self.stored.add(node.id)
            elif isinstance(node.ctx, ast.Del):
                self.deleted.add(node.id)
    
    # Sample usage
    if __name__ == '__main__':
        # Some Python code
        code = '''
        for i in range(10):
            print(i)
        del i
        '''
    
        # Parse into an AST
        top = ast.parse(code, mode='exec')
    
        # Feed the AST to analyze name usage
        c = CodeAnalyzer()
        c.visit(top)
        print('Loaded:', c.loaded)
        print('Stored:', c.stored)
        print('Deleted:', c.deleted)
    如果你运行这个程序,你会得到下面这样的输出:
    
    Loaded: {'i', 'range', 'print'}
    Stored: {'i'}
    Deleted: {'i'}
    最后,AST可以通过 compile() 函数来编译并执行。例如:
    
    >>> exec(compile(top,'<stdin>', 'exec'))
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>>
    
    2020-04-17 16:28:37
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
神龙云服务器产品及技术深度解析 立即下载
弹性创造价值:基于ECS的最佳性价比实践解析 立即下载
又快又稳:阿里云下一代虚拟交换机解析 立即下载