【发布时间】:2017-03-05 13:58:00
【问题描述】:
我正在为在线编程上下文编写一些工具。
它的一部分是一个测试用例检查器,它实际上基于一组(输入,输出)文件将检查解决方案方法是否实际工作。
基本上,求解方法预计定义如下:
def solution(Nexter: inputs):
# blahblah some code here and there
n = inputs.next_int()
sub_process(inputs)
# simulating a print something
yield str(n)
然后可以翻译(一旦 AST 修改)为:
def solution():
# blahblah some code here and there
n = int(input())
sub_process()
print(str(n))
注意:Nexter 是一个定义为用户 input() 生成器是否调用或执行预期输入 + 其他一些好处的类。
我知道与从 AST 转换回源代码相关的问题(需要依赖第 3 方的东西)。我也知道有一个 NodeTransformer 类:
- http://greentreesnakes.readthedocs.io/en/latest/manipulating.html
- https://docs.python.org/3/library/ast.html#ast.NodeTransformer
但我仍然不清楚它的用途我不知道我是否最好检查调用、expr 等。
下面是我最终得到的结果:
signature = inspect.signature(iterative_greedy_solution)
if len(signature.parameters) == 1 and "inputs" in signature.parameters:
parameter = signature.parameters["inputs"]
annotation = parameter.annotation
if Nexter == annotation:
source = inspect.getsource(iterative_greedy_solution)
tree = ast.parse(source)
NexterInputsRewriter().generic_visit(tree)
class NexterInputsRewriter(ast.NodeTransformer):
def visit(self, node):
#???
这绝对不是有史以来最好的设计。下一次,当传递给测试器类断言是否实际输出与预期匹配。
总结一下我想要实现的目标,但我真的不知道如何实现(除了子类化 NodeTransformer 类):
- 去掉求解函数参数
- 修改方法主体中的输入调用(以及方法的子调用也利用 Nexter: 输入),以便将它们替换为实际的用户 input() 实现,例如
inputs.next_int() = int(input())
编辑
找到了该工具 (https://python-ast-explorer.com/),该工具对可视化用于给定函数的 ast.AST 导数有很大帮助。
【问题讨论】:
-
我不清楚你真正想要做什么。我的理解是,您希望从要测试的 python 脚本的原始文本开始,并且您希望修改该脚本源以使您能够针对它运行自动化测试。 [请确认]。如果我没猜错的话,你想要的脚本修改工具就是程序转换系统。请参阅我的 SO 答案,了解如何在 stackoverflow.com/a/39945762/120163 修改脚本
-
实际上更多的是相反,我的函数定义本身是可测试的,但我想转换它以替换输入:Nexter 调用各自的实现并删除输入:Nexter 作为参数函数定义。
-
我将您的回答解释为“我想修改现有代码以控制其获取输入的方式”。如果您这样做不是为了使其更可测试,那么您为什么要这样做?在任何情况下,您都希望以常规方式修改代码。我的链接建议成立。
-
你会发现很多修改 ast 的例子:github.com/QQuick/Transcrypt/blob/master/transcrypt/modules/org/…。搜索“即时”。您还可以使用 -dt 选项运行 Transcrypt 以生成人类可读的语法树。这就是我发现如何进行转换的方式。这是一个 3 步过程: 1. 解析。 2. 使用原始节点的信息生成修改节点。 3.访问它以生成修改后的代码。
标签: python python-3.x abstract-syntax-tree