我以前使用过这种方法,将 IronPython 脚本保存在数据库和文件中。我喜欢的模式是使用约定俗成的名称存储 Python 函数。换句话说,如果您正在处理 Foo 类型的对象,您的 .py 文件或表中可能有一个名为“foo_filter”的 Python 函数。最终,您可以执行 Python 文件并将函数解析为函数引用字典。
快速示例应用程序...
你的 foo 类:
public class Foo {
public string Bar { get; set; }
}
设置 Foo 并调用 getPythonFunc(i);
var items = new List<Foo>() {
new Foo() { Bar = "connecticut" },
new Foo() { Bar = "new york" },
new Foo() { Bar = "new jersey" }
};
items.ForEach((i) => { getPythonFunc(i); Console.WriteLine(i.Bar); });
一个快速而肮脏的 getPythonFun 实现... ScriptXXX 对象图显然应该被缓存,GetVariable() 检索的变量也应该被缓存。
static void getPythonFunc(Foo foo) {
ScriptRuntimeSetup setup = ScriptRuntimeSetup.ReadConfiguration();
ScriptRuntime runtime = new ScriptRuntime(setup);
runtime.LoadAssembly(Assembly.GetExecutingAssembly());
ScriptEngine engine = runtime.GetEngine("IronPython");
ScriptScope scope = engine.CreateScope();
engine.ExecuteFile("filter.py", scope);
var filterFunc = scope.GetVariable("filter_item");
scope.Engine.Operations.Invoke(filterFunc, foo);
}
filter.py的内容:
def filter_item(item):
item.Bar = item.Bar.title()
一种基于属性应用规则的简单方法(不是在 Foo 上添加 Size 属性):
var items = new List<Foo>() {
new Foo() { Bar = "connecticut", Size = "Small" },
new Foo() { Bar = "new york", Size = "Large" },
new Foo() { Bar = "new jersey", Size = "Medium" }
};
更改 getPythonFun() 中调用 ScriptScope 的 GetVariable() 的行:
var filterFunc = scope.GetVariable("filter_" + foo.Size.ToLower());
还有filter.py的新内容
def filter_small(item):
item.Bar = item.Bar.lower()
def filter_medium(item):
item.Bar = item.Bar.title()
def filter_large(item):
item.Bar = item.Bar.upper()
我在http://www.codevoyeur.com/Articles/Tags/ironpython.aspx 有一堆更完整的示例。