使用Python的ast库解析.py文件后,计算函数代码行数时出错

8cdiaqws  于 2023-04-10  发布在  Python
关注(0)|答案(1)|浏览(125)

AST处理后的行计数是不完整的,只有前两个是完整的,而'draw questions'之后的所有内容都是不完整的。lineCount.py

import ast

def get_function_info(file_path):
    with open(file_path, 'r') as f:
        tree = ast.parse(f.read())
        functions = [node for node in tree.body if isinstance(node, ast.FunctionDef)]
        function_info = []
        for function in functions:
            function_name = function.name
            function_line_count = function.body[-1].lineno - function.body[0].lineno + 1
            function_info.append((function_name, function_line_count))
        print(len(functions))
        print(function_info)
        return len(functions), function_info

get_function_info('mathQuiz.py')

mathQuiz.py是要计数的文件,如下所示

import turtle
import random
import math

def draw_square():
    turtle.penup()
    turtle.forward(100)
    turtle.pendown()
    turtle.forward(50)
    turtle.left(90)
    turtle.forward(25)
    turtle.left(90)
    turtle.forward(50)
    turtle.left(90)
    turtle.forward(25)
    turtle.left(90)

def generate_question():
    operators = ['+', '-', '*', '/']
    questions = set()  
    while len(questions) < 5 * 3:
        operator = random.choice(operators)  
        if operator == "+":
            a = random.randint(0, 99)  
            b = random.randint(0, 99 - a)  
            result = a + b  
        elif operator == "-":
            a = random.randint(1, 99)  
            b = random.randint(1, a)  
            result = a - b  
        elif operator == "*":
            a = random.randint(1, math.floor(math.sqrt(99)))  
            b = random.randint(1, math.floor(math.sqrt(99)))
            result = a * b
        else:
            result = random.randint(1, math.floor(math.sqrt(99)))  
            b = random.randint(1, math.floor(math.sqrt(result)))
            a = result * b
        question = f'{a} {operator} {b} = '  
        if question not in questions:  
            questions.add(f'{question}{result}')
    return questions

def draw_question(questions):
    turtle.penup()
    turtle.goto(-200, 200)
    turtle.pendown()
    for i, question in enumerate(questions):
        turtle.write(question, font=('Arial', 16, 'normal'))  
        draw_square()

        if i % 3 == 2:  
            turtle.penup()
            turtle.goto(-200, turtle.ycor() - 50)
            turtle.pendown()
        else:  
            turtle.penup()
            turtle.goto(turtle.xcor() + 75, turtle.ycor())
            turtle.pendown()

def draw_answer(questions):
    turtle.penup()
    turtle.goto(-200, -100)
    turtle.pendown()
    for i, question in enumerate(questions):
        turtle.write(question, font=('Arial', 16, 'normal'))  
        
        draw_square()
        
        if i % 3 == 2:
            turtle.penup()
            turtle.goto(-200, turtle.ycor() - 50)
            turtle.pendown()
        else:
            turtle.penup()
            turtle.goto(turtle.xcor() + 75, turtle.ycor())
            turtle.pendown()

def put_answer(answers):
    turtle.penup()
    turtle.goto(-100, -100)
    turtle.pendown()
    for i, answer in enumerate(answers):
        turtle.write(answer, font=('Arial', 16, 'normal'))  
        
        if i % 3 == 2:
            turtle.penup()
            turtle.goto(-100, turtle.ycor() - 50)
            turtle.pendown()
        else:
            turtle.penup()
            turtle.goto(turtle.xcor() + 175, turtle.ycor())
            turtle.pendown()


turtle.hideturtle()  
turtle.speed(0)  

turtle.penup()
turtle.goto(-250, 250)
turtle.write("Quiz", font=("Arial", 24, "normal"))
turtle.pendown()
turtle.forward(100)

questions = generate_question()
questions_without_answer = [question.split('=')[0] + ' = ' for question in questions]  
draw_question(questions_without_answer)

turtle.penup()
turtle.goto(-250, -50)
turtle.write("Answer", font=("Arial", 24, "normal"))
turtle.pendown()
turtle.forward(100)

draw_answer(questions_without_answer)

answers = [question.split('=')[1] for question in questions]
put_answer(answers)

turtle.done()

我不明白这段代码有什么问题,希望得到正确的行处理结果。

vsdwdz23

vsdwdz231#

您的get_function_info函数似乎适用于以不缩进行开始和结束的函数体。这里有一个使用inspect模块的替代解决方案。请注意,get_function_info的参数只是模块的名称,而不是完整的文件名。

import inspect
import importlib

def get_function_info(module_name):
    """Parse a file and return the number of lines of code in each function."""
    module = importlib.import_module(module_name)
    functions = inspect.getmembers(module, inspect.isfunction)
    function_info = []
    for name, value in functions:
        function_line_count = len(inspect.getsourcelines(value)[0]) - 1
        function_info.append((name, function_line_count))
    return len(functions), function_info

num, info = get_function_info("mathQuiz")
print(num)
print(info)

输出:

5
[('draw_answer', 16), ('draw_question', 15), ('draw_square', 11), ('generate_question', 24), ('put_answer', 14)]

您还需要将mathQuiz模块中的未缩进代码 Package 在main函数中,并像下面这样调用它,以避免在导入模块时执行程序。

if __name__ == "__main__":
    main()

相关问题