我想解析一个字符串,例如:
code_str = """
def foo(a, b):
return a + b
foo(
a=1,
b=2
)
"""
获取“可执行”字符串列表(多行与否)
code_snippets = extract_executable_strings(code_str)
assert code_snippets = [
"def foo(a, b):\n\treturn a + b\n",
"foo(\n\ta=1\n\tb=2\n)\n"
]
这样我就可以一一执行片段,或者生成一个等效的 doctest 字符串,例如:
"""
>>> def foo(a, b):
... return a + b
>>>
>>> foo(
... a=1,
... b=2
... )
"""
当然,正则表达式可以涵盖简单的情况,但要涵盖所有有效的python,似乎我应该利用python的解析器本身,而不是自己重写(一个糟糕的)解析器。
答案 0 :(得分:0)
这是完成问题描述的确切工作的函数。
from ast import parse as ast_parse
try:
# Try ast.unparse (3.9+)
from ast import unparse as ast_unparse
except ImportError:
try:
from astunparse import unparse as ast_unparse
except ModuleNotFoundError:
raise ModuleNotFoundError(
"Can't find a ast unparse function -- you'll need python 3.9+ or (pip/conda) install astunparse")
def extract_executable_strings(code_str: str):
"""Extract code blocks from code_str
>>> code_str = '''
... def foo(a, b):
... return a + b
...
... foo(
... a=1,
... b=2
... )
... '''
>>> blocks = list(extract_executable_strings(code_str))
>>> len(blocks)
2
>>> print(blocks[0])
def foo(a, b):
return (a + b)
>>> print(blocks[1])
foo(a=1, b=2)
"""
for ast_obj in ast_parse(code_str).body:
yield ast_unparse(ast_obj).strip()