沙盒/逐行运行python代码

Mor*_*sen 13 python interpreter programming-languages development-environment dynamic

我希望能够像这两个人那样做:

发明原则@ 18:20, Live ClojureScript游戏编辑器

如果您不想查看视频,我的问题是:

说我有这个代码:

....
xs = []
for x in xrange(10):
    xs.append(x)
...
Run Code Online (Sandbox Code Playgroud)

我想创建一个环境,我可以在其中执行代码,语句语句以及在更改时观察/跟踪locals/globals.也许给它一个变量列表来跟踪locals/globals字典.就像单步执行代码并保存状态信息一样.

最理想的是,我想保存每个状态及其关联的上下文数据(locals/globals),以便我可以验证谓词.

我想做一些像布雷特·维克多的二元搜索示例,发明原则@ 18:20

我有道理吗?我发现在文本中解释很复杂,但视频展示了我想要尝试的内容:)

谢谢你的时间


我试过/读/ googled:

我的下一步是研究ast和编译代码并逐位运行它,但我真的需要一些指导..我应该更多地考虑反射和inspect模块?

我之前使用过Spin模型检查器,但它使用自己的DSL,我只是喜欢在实现语言中进行建模,在本例中是python.

哦,顺便说一句,我知道沙盒代码的安全含义,但我并没有尝试建立一个安全的执行环境,我正在尝试创建一个非常交互的环境,例如针对原始模型检查或谓词断言.

Don*_*kby 7

我经过了初步的成功sys.settrace(),我最终切换到ast模块(抽象语法树).我解析我想要分析的代码,然后在每次赋值后插入新的调用来报告变量名称及其新值.我还插入调用报告循环迭代和函数调用.然后我执行修改后的树.

        tree = parse(source)

        visitor = TraceAssignments()
        new_tree = visitor.visit(tree)
        fix_missing_locations(new_tree)

        code = compile(new_tree, PSEUDO_FILENAME, 'exec')

        self.environment[CONTEXT_NAME] = builder
        exec code in self.environment
Run Code Online (Sandbox Code Playgroud)

我正在研究像Bret Victor这样的实时编码工具,你可以在GitHub上看到我的工作代码,以及它在测试中如何表现的一些例子.您还可以从项目页面中找到演示视频,教程和下载的链接.


Don*_*kby 5

更新:在我使用这项技术取得初步成功后,我转而使用其他答案中ast所述的模块。

sys.settrace()似乎工作得很好。我接受了你提到的hacks 问题Andrew Dalke 的文章,并让这个简单的例子工作。

import sys

def dump_frame(frame, event, arg):
    print '%d: %s' % (frame.f_lineno, event)
    for k, v in frame.f_locals.iteritems():
        print '    %s = %r' % (k, v)
    return dump_frame

def main():
    c = 0
    for i in range(3):
        c += i

    print 'final c = %r' % c

sys.settrace(dump_frame)

main()
Run Code Online (Sandbox Code Playgroud)

我必须解决两个问题才能使其正常工作。

  1. 如果您想继续跟踪,跟踪函数必须返回自身或另一个跟踪函数。
  2. 跟踪似乎只在第一次函数调用之后开始。我原本没有main方法,直接进入循环。

这是输出:

9: call
10: line
11: line
    c = 0
12: line
    i = 0
    c = 0
11: line
    i = 0
    c = 0
12: line
    i = 1
    c = 0
11: line
    i = 1
    c = 1
12: line
    i = 2
    c = 1
11: line
    i = 2
    c = 3
14: line
    i = 2
    c = 3
final c = 3
14: return
    i = 2
    c = 3
38: call
    item = <weakref at 0x7febb692e1b0; dead>
    selfref = <weakref at 0x17cc730; to 'WeakSet' at 0x17ce650>
38: call
    item = <weakref at 0x7febb692e100; dead>
    selfref = <weakref at 0x7febb692e0a8; to 'WeakSet' at 0x7febb6932910>
Run Code Online (Sandbox Code Playgroud)