当前位置: 首页 > 知识库问答 >
问题:

如何在python中解析循环语句的开始和结束

喻渊
2023-03-14

我的目标是在python中找到循环语句的开始和结束的行号。

示例场景

#A.py
Line1: a=0                  
Line2: while a<5:           
Line3:    print a          
Line4:    a=a+1 

Desired output:
Start of a loop Line2 
End of a loop   Line4 

当前解析器代码

#parser.py
with open(a) as f:
    tree = ast.parse(f.read())
taskline=[]
for node in ast.walk(tree):
    if isinstance(node, (ast.For)) or isinstance(node,(ast.While)):                        
        print node.lineno-1  <-- This give line number on for the start of a loop              

我想实现上述输出。我使用AST解析给定的文件并确定循环的出现。通过AST解析,我能够找到循环开始时的行号,但循环结束时的行号尚未确定。是否有任何方法可以解析整个循环语句并确定其起始行号和结束行号?

共有3个答案

太叔鸿
2023-03-14

我对ast模块不是非常熟悉,但是下面的代码在一些测试示例中对我有用。它返回一个2元组列表,文件中每个循环一个元组,其中每个元组看起来像(开始行,结束行)

def get_loop_boundaries(fname):
    boundaries = []

    with open(fname) as f:
        tree = ast.parse(f.read())

    for node in ast.walk(tree):
        if isinstance(node, (ast.For)) or isinstance(node,(ast.While)):
            loop_start = node.lineno

            # body attribute is a list of nodes, one for each line in the loop
            # the lineno of the last node will give us the ending line
            loop_end = node.body[-1].lineno

            # add 2-tuple of starting and ending lines for current loop to list
            boundaries.append((loop_start, loop_end))
    # return a list of starting and ending lines for all loops in fname file
    return boundaries

我刚刚意识到这个函数的主要逻辑可以更简洁地写成列表理解:

return [(node.lineno, node.body[-1].lineno) for node in ast.walk(tree) if isinstance(node, (ast.For, ast.While))]
越姚石
2023-03-14

它可能是复杂的,但你可以尝试以下算法。

1. Count the number of white spaces before while. say it ident(you can use something like this len(a) - len(a.lstrip()) )
2. countinue reading the next line and counting the white spaces before the line say currIdent.
3. when ever currIdent = ident, then end of loop is line before it.
宋正真
2023-03-14

While节点在其节点中有其语句。正文列表。while循环的最后一行是列表的最后一个元素。我不知道你为什么要减去一(除非你的文件a有一条你想假装不存在的注释):

$ cat a.py
a = 0 
while a < 5:
    print a
    a += 1
for i in (1, 2, 3): 
    pass
$ cat ast_ex.py
import ast

with open('a.py') as f:
    tree = ast.parse(f.read())

for node in ast.walk(tree):
    if isinstance(node, (ast.For, ast.While)):
        print 'node:', node, 'at line:', node.lineno
        print 'body of loop ends at:', node.body[-1].lineno
$ python ast_ex.py 
node: <_ast.While object at 0x8017a8e50> at line: 2
body of loop ends at: 4
node: <_ast.For object at 0x8017ac0d0> at line: 5
body of loop ends at: 6

循环中的第一行在body[0]中(如果循环中只有一条语句,则可能与body[-1]相同)。

 类似资料:
  • 我如何使它再次循环回到FOR循环的开始?我试着寻找答案。continue的用法似乎对我不起作用。

  • 我有这个任务:-编写一个错误陷阱条件循环,反复询问用户的用户名和密码输入,直到输入正确的值。 < li >如果用户名 这是我到目前为止写的: 我真的不知道如何处理第三个条款。

  • 问题内容: 我知道如何在单独的行上同时使用for循环和if语句,例如: 而且我知道当语句很简单时,我可以使用列表推导来组合这些内容,例如: 但是我找不到一个很好的例子,可以在任何地方(复制和学习)演示一组复杂的命令(不仅仅是“ print x”),这些命令是在for循环和某些if语句组合后发生的。我期望的是: 这不是python应该工作的方式吗? 问题答案: 您可以使用以下生成器表达式:

  • Python 中,while 循环和 if 条件分支语句类似,即在条件(表达式)为真的情况下,会执行相应的代码块。不同之处在于,只要条件为真,while 就会一直重复执行那段代码块。 while 语句的语法格式如下: while 条件表达式:     代码块 这里的代码块,指的是缩进格式相同的多行代码,不过在循环结构中,它又称为 循环体。 while 语句执行的具体流程为:首先判断条件表达式的值,

  • 通常都听到别人说,计算机很牛逼,很聪明,其实计算机一点都不聪明,光是你要跟他沟通,都会气 shi 你,聪明的是在写程序的你。 写程序就是跟计算机沟通,告诉它要做什么。 竟然是这样,那么肯定缺少不了一些沟通逻辑。比如你要告诉计算机在什么情况下做什么?或者在哪个时间点做什么? 这都需要用到逻辑判断。这一章节,主要就是说这个。 目录

  • 我在研究mysqli准备的声明,我有两个问题。 在阅读过程中,我发现预处理语句的执行顺序如下所示: 这是我的第一个问题: 在我阅读时,它还提到以下内容: 如果不将结果绑定到变量,请使用$row=$stmt- 他们使用这两种方法中的任何一种来循环结果集是否有任何优点/缺点?如果没有区别,那么为什么还要麻烦使用$stmt绑定结果呢- 这是我的另一个问题: $stmt- 希望你的回答能让我更好地理解事先