Introduction
IronPython is an open source implementation of the
Python programming language for .NET Framework. Python itself is an interpreted high-level programming language; it is often compared to
Java or
Ruby. Python has a very clear and readable syntax, intuitive object oriented approach and it is embeddable within applications via scripting interface. If you are new to Python I recommend browsing through the
python documentation.
IronPython is implemented on top of the
Dynamic Language Runtime (DLR). DLR makes it easier to develop dynamic languages which are intended to run on .NET Framework. DLR is essentially a library which runs on top of the
Common Language Runtime.
Python is often embedded in applications to allow a plug-in like functionality; because Python is also a high-level, dynamic and interpreted programming language it is also easy to add new functionality. IronPython might be useful in scenarios where your customers require custom business logic. Your application could perform main operations on the data while the scripts would contain the business logic and could easily be edited on-site and quickly deployed to your customers. It is also worth mentioning that some standard Python libraries might not work with IronPython.
The goal of this article is to show you:
• how to include IronPython in your Application
• how to work with the basic Python data structures and a simple for loop
• how to execute Python scripts and retrieve values from methods
• how to call Python methods using the dynamic keyword
Creating a project
First you will need to download and install IronPython, which you can do
here. After you've installed IronPython it is time to create a new
WinForms project.
Next, you need to reference IronPython assemblies. Please note that IronPython will
not be registered in
Add References dialog box so you will have to manually navigate to the IronPython installation directory and add references from there.
You can always add the assemblies manually to the
Add References dialog box, you can learn more in this
article. Please note that this only works for Visual Studio 2008. For Visual Studio 2010 you need to add a new key at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\.NETMinimumVersion\AssemblyFoldersEx
Your first script
First you need to add a new python file to your project. Right click on the project and select
Add -> New Item. Select a text file and name it
script.py.
After you've added the file you will need to right click on the
script.py in
Solution Explorer, select
Properties and set
Copy to Output Directory to
Copy always
Now it's time to open the
script.py and write our python code. Please note that indention is
very important in Python programming.
def
HelloWorld():
return
'Hello World'
def
SimpleLoop():
retVal
=
0
for
i
in
range(
1
,
10
):
retVal
=
retVal
+
i
return
retVal
def
List():
return
[
1
,
2
,
3
]
def
Dictionary():
return
{
"1"
:
"1"
,
"2"
:
"2"
}
In the code I am demonstrating a for loop, lists and dictionaries. In Python, a list is always declared with angle ("[]") brackets and commas are used to separate the values. Dictionary is always declared with curly ("{}") brackets and keys and values are also separated with commas. Python lists can contain any type: integers, floats, string or other lists. Same also applies to dictionaries.
Executing the script
In this part I will show you how to get a list of methods in the script, how to call these methods and how to get the results.
Now it's time to come back to the Windows Forms project. I added a combobox, a textbox and a button onto the form. I used the combobox to list out available methods, textbox shows the python output and the button calls the selected python function.
This is the code which I used to extract the method names from the script.
private
void
ExtractMethods()
{
try
{
ScriptEngine engine = Python.CreateEngine();
// not exactly by the book
ScriptScope scope = engine.ExecuteFile(
"script.py"
);
foreach
(var item
in
scope.GetItems().Where(p => p.Value
is
IronPython.Runtime.PythonFunction))
{
comboBox1.Items.Add(item.Key);
}
engine.Runtime.Shutdown();
}
catch
{}
}
I actually executed the whole script to see the contents; this is not something you'll be doing in an actual business environment scenario. However, there will be times when you will need to see a list of methods in a particular script and this is one example of how to do it.
This is the code which I used to call the methods and grab the return values.
private
void
CallPythonMethod(
string
methodName)
{
try
{
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.ExecuteFile(
"script.py"
);
var v = engine.Operations.Invoke(scope.GetVariable(methodName));
textBox1.Text =
"Result: "
;
if
(v
is
string
)
textBox1.Text += v;
else
if
(v
is
int
)
textBox1.Text += ((
int
)v).ToString();
else
if
(v
is
IronPython.Runtime.List)
((IronPython.Runtime.List)v).ToList().ForEach(p => textBox1.Text +=
string
.Format(
"{0}{1}"
, Environment.NewLine, p.ToString()));
else
if
(v
is
IronPython.Runtime.PythonDictionary)
{
foreach
(var item
in
((IronPython.Runtime.PythonDictionary)v))
{
textBox1.Text +=
string
.Format(
"{2}key: {0}, value {1}"
, item.Key, item.Value, Environment.NewLine);
}
}
engine.Runtime.Shutdown();
}
catch
{
textBox1.Text =
string
.Format(
"Error executing: {0}"
, methodName);
}
}
As you can see, our script is executed every time this method is called. In a realistic scenario you will probably find this redundant. However, it is useful in scenarios where Python source code changes and you want to see these change take effect without restarting the application.
Using the dynamic keyword
Dynamic keyword is a new feature in
C# 4.0. DLR was originally part of the first framework of IronPython, and has since been used to introduce new features into
C# 4.0. One of them is the
dynamic keyword.
In this final part I want to show you how to call Python methods using the
dynamic keyword:
ScriptRuntime runtime = Python.CreateRuntime();
dynamic script = runtime.UseFile(
"script.py"
);
script.HelloWorld();
Please note that because IronPython is an interpreted scripting language it relies on the
dynamic keyword which in turn breaks strong type checking.
Conclusion
This article is meant to introduce you to IronPython and to show you the very basics of hosting IronPython in your Application and how to call scripts from your Application. I will demonstrate more advanced features in a follow up article in the near future. You can download the source code used in this article below.