Archive

Archive for September, 2011

Calling IronPython from C#

September 16, 2011 2 comments

There are a lot of great Python libraries out there, and IronPython makes it really easy to call many of them from .NET. Over the years, IronPython has become easier to embed in your applications, and the DLR that was added in .NET 4 makes it dead simple.

Say you have a Python expression (could be an entire module) in a string variable called “expression” – the code to execute that is this simple:

var engine = IronPython.Hosting.Python.CreateEngine();
var script = engine.CreateScriptSourceFromString(expression);
var scope = engine.CreateScope();
dynamic result = script.Execute(scope);

When you execute that, your result will be whatever you returned from the Python expression. You could return a value or a function defined in Python. If your expression is a Python lambda taking three parameters, from your C# code you can write the following:

dynamic foo = result(a,b,c);

If you need to load additional .NET assemblies to expose them to the IronPython code, just call the following:

engine.Runtime.LoadAssembly(assembly);

What about passing parameters? The scope let’s you pass in a dictionary of parameters. The key to each dictionary entry is the name the parameter will have inside the IronPython scope, and the value is going to be the value of that parameter when script.Execute(scope) is called. To pass a dictionary of parameters, simply do this:

var parameters = new Dictionary<string,object>() {
   { "age", 30 }, { "name", "Vinny" }
}
scope = engine.CreateScope(parameters);
result = script.Execute(scope);

The parameters “age” and “name” will be passed into the scope of the IronPython script being executed.

Suppose you have additional Python modules that you want to call from your embedded IronPython. IronPython ships with quite a bit of the standard library, but your embedded code doesn’t necessarily know how to find it. A call to engine.SetSearchPaths(paths) adds a collection of strings with paths that IronPython should search when executing your code.

var paths = new List<string>();
paths.Add("c:\path\to\my\modules");
engine.SetSearchPaths(paths);

I encourage you explore the options for embedding IronPython in your own applications. The ScriptEngine is quite robust; you can execute string expressions or entire files, in the same AppDomain or in a new one.

Categories: C#, DLR, IronPython