好的,如果我有以下代码:
a = 1
b = 2
count_one = 0
count_two = 0
ex_array = [a,b]
for i in ex_array:
print(i)
if i == 2:
print("Two")
elif i == 1:
print("One")
我的目标是将代码分类为代码块(和子块)。
我的意思是:
一个块就是整个代码,我们称之为“一级”。 在“一级”块内还有:
for i in ex_array:
print(i)
if i == 2:
print("Two")
elif i == 1:
print("One")
我们称之为“二级”块。 在二级区块内还有:
if i == 2:
print("Two")
和
if i == 1:
print("One")
此级别为“三级”:
因此,“第一级”中有 1 个代码块(完整代码),“第二级”中有 1 个代码块(包含
for
和 if
语句的 elif
循环)和第三级中有 2 个代码块(if
和 elif
陈述)。
一旦我对代码块和级别进行了分类,我想将它们添加到字典中,如下所示:
code_block_dictionary = {0:(0,"Entire code"), 1:(1,"The for loop block"), 2:(2,"The if statement"), 3:(2,"The `elif` statement")}
第一个数字是索引/键,第二个数字是级别,第三个数字是该级别的代码。
最后,我希望能够做这样的事情:
输入级别以选择块:
我输入“3”
此级别有 2 个代码块
输入要打印的块号:
我输入“1”,打印到终端的结果字符串是:
if i == 2:
print("Two")
我希望这一切都是有道理的。 如果需要更多信息,请询问,我会尽力而为。 谢谢
您可以使用 ast 模块 通过自定义 AST 解析来完成此操作。 我可能会稍微迟到,但如果其他人有兴趣解决这个问题:
import ast
def visit(node: ast.AST, depth: int = 0):
"""Visit a node to look for child blocks."""
# Fields that indicate this is a block.
FIELDS = {"body", "orelse", "finalbody"}
if any((key in FIELDS) for key, _ in ast.iter_fields(node)):
yield (depth, ast.unparse(node))
# Iterate over the fields for the current node.
for key, value in ast.iter_fields(node):
if key in FIELDS:
if isinstance(value, list):
for item in value:
if isinstance(item, ast.AST):
yield from visit(item, depth + 1)
elif isinstance(value, ast.AST):
yield from visit(node, depth + 1)
if __name__ == "__main__":
path = ...
with open(path) as f:
source = f.read()
tree = ast.parse(source)
for block in visit(tree):
print(block)
此代码为您提供了一个具有深度的生成器和源代码。
注意:它不会为您提供原始源代码(请参阅 ast.unparse),但您可以使用
lineno
和 end_lineno
字段来获取它。