分析IronPython中的代码链
本文关键字:代码 IronPython 分析 | 更新日期: 2023-09-27 18:14:21
ironpython中是否有帮助分析python代码的方法?
例如下面这个脚本
def bar(b):
return foo(b)
def foo(f):
return filters.delta(f) #This is a reference added to the scope from C#
x = 1
bar(x)
我需要知道filters.delta
如何在脚本中调用,如bar(x)> foo(b)> filters.delta(f)
这可以从IronPython完成还是我需要自己解析脚本?这不是很容易做到的
<<p> 背景信息/strong>这个软件叫做FreePIE。它是一个可编写脚本的输入输出模拟器。它有一组util函数。考虑以下代码:
mouse.deltaX = filters.delta(joystick[0].x)
它获取操纵杆或手柄的绝对x坐标,使用filers.delta
获得delta值并设置鼠标的相对x坐标
为了得到delta值,我的软件必须在脚本执行之间比较两个样本,util函数负责这个。
[NeedIndexer]
public double delta(double x, string indexer)
{
var lastSample = x;
if (deltaLastSamples.ContainsKey(indexer))
lastSample = deltaLastSamples[indexer];
deltaLastSamples[indexer] = x;
return x - lastSample;
}
但是为了解决这个问题,它需要存储最后一个样本。正如您所看到的,它接受一个字符串,该字符串可以索引包含最后一个示例的集合。为了简单,我不想要求用户处理这个索引。所以我所做的是准备脚本,并寻找具有[NeedIndexer]
属性的所有方法。如果我找到一个,我会解析方法参数并将其用作索引器。因此,像上面这样的python脚本在解析
mouse.deltaX = filters.delta(joystick[0].x, "joystick[0].x")
在这个例子中,代码将工作,因为joystick[0].x
是唯一的,但是如果用户定义一个python函数并从那里使用filters.delta
,他将索引所有样本的相同变量名。
解析脚本的当前代码https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.Core/ScriptEngine/Python/PythonScriptParser.cs L135
我希望我能说清楚我想要达到的目标
多亏了Jeff的回答,我才有了更进一步的了解
var engine = IronPython.Hosting.Python.CreateEngine();
var script = @"def foo(y):
return filters.delta(y)
def bar(x):
return foo(x)
bar(-5)
";
var ast = @"import ast
tree = ast.parse(script)
callback(ast.dump(tree))";
var callback = new Action<object>(o =>
{
Console.WriteLine(o);
});
engine.SetSearchPaths(new[] { "pylib" });
var scope = engine.CreateScope();
scope.SetVariable("script", script);
scope.SetVariable("callback", callback);
engine.Execute(ast, scope);
我已经能够使用ast.dump
将整个树转储为字符串,但我还没有发现如何递归地迭代树。我需要这样做,直到我找到一个filters.delta
调用,然后再次遍历备份并向链中的每个函数添加一个参数。网上没有太多关于最后一个模块的信息。有人知道这是怎么实现的吗?对象上有一个_fields
成员它是由ast.parse
返回的但是我找不到从那里去
首先,我认为你应该重新考虑你是怎么做的。任何解决方案都将是脆弱和神奇的,并且可能在未来的道路上造成更多的问题。像mouse.deltaX = joystick[0].x_filters.delta()
这样的东西会更清楚。你甚至可以动态地创建x_filters
(它不一定是操纵杆类型的一部分),方法是用DynamicObject包装器包装操纵杆,根据需要创建x_filters
。
如果你想修改脚本,你可能想使用ast模块来解析代码。你仍然需要走最后一圈来寻找那个函数。是否处理绑定到不同名称的函数等取决于您。最后一个模块也应该为您提供符号的文本位置,以便您可以在其后面插入特殊代码。
你也可以在运行时使用sys。settrace,如果你在创建引擎时启用"Tracing"选项,它应该在IronPython下工作。但这可能对您的目的来说太晚了。