Python
is a powerful and versatile programming language that has become increasingly popular. For many, it’s one of the very first programming languages they pick up when getting started. Some of the highest traffic posts on my blog many years after they were written look at using C# and Python together. Today, we’re going to explore how you can use Python from inside a C# .NET Core application with much more modern approaches than my
original articles
. Enter Pythonnet!
Pythonnet Package & Getting Started
We’re going to be looking at
Python for .NET
in order to accomplish this goal. This library allows you to take advantage of Python installed on the running machine from within your .NET Core applications. You must configure it to point at the corresponding Python DLL that you’d like to use, and after a couple of lines of initialization, you’re off to the races!
Example 1 – Hello World with Pythonnet
To get started, you’ll need to install the
pythonnet
package from NuGet
. Once you’ve done that, you can use the following code to run a Python script from your C# code:
using Python.Runtime;
internal sealed class Program
private static void Main(string[] args)
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
using var scope = Py.CreateScope();
scope.Exec("print('Hello World from Python!')");
This code sets our python DLL path on the Runtime, which will be a necessary step. Don’t forget to do this! We must then call PythonEngine.Initialize()
and Py.GIL()
, which we will want to dispose of later so consider a using
statement. We can ask the static
Py
class to create a scope for us to use, and then leverage the Exec method in order to execute some Python code. In this example, we’re calling the Exec method to run a simple Python script that prints “Hello World from Python!
” to the console.
Example 2 – A Pythonnet Calculator!
You can also use the Python C API to call Python functions directly from C# code. To do this, you’ll need to create a C# wrapper for the Python function you want to call. Here’s an example of how you might create a wrapper for a Python function that takes two integers as arguments and returns their sum:
using System;
using Python.Runtime;
internal sealed class Program
private static void Main(string[] args)
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
Console.WriteLine("Enter first integer:");
var firstInt = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second integer:");
var secondInt = int.Parse(Console.ReadLine());
using dynamic scope = Py.CreateScope();
scope.Exec("def add(a, b): return a + b");
var sum = scope.add(firstInt, secondInt);
Console.WriteLine($"Sum: {sum}");
In this example, we’re using the Exec method to define a Python function called add
that takes two integers as arguments and returns their sum
. Thanks to the dynamic keyword in C#, we are able to make an assumption that our scope
object has a method called add
directly on it. Finally, we use C# code directly to call the add
method just like as if it was inside of C#. The return type assigned to the sum
variable in C# is also dynamic, but you could declare this variable as an integer and it will compile properly with this type as well.
The results in the console window from our simple Pythonnet calculator!
Example 3 – Object Interop
We can also pass Python objects to C# functions and vice versa. Here’s an example of how you might receive a Python list back to C# function and iterate over its elements without using the dynamic keyword:
using Python.Runtime;
internal sealed class Program
private static void Main(string[] args)
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
using var scope = Py.CreateScope();
scope.Exec("number_list = [1, 2, 3, 4, 5]");
var pythonListObj = scope.Eval("number_list");
var csharpListObj = pythonListObj.As<int[]>();
Console.WriteLine("The numbers from python are:");
foreach (var value in csharpListObj)
Console.WriteLine(value);
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
In this example, we’re using the Exec method to create a Python list and assign it to a variable called number_list
. We then use the Eval method to get a reference to the list
object and then we can call As<T>
with an integer array (denoted as int[]
) to convert the result. At this point, csharpListObj
is a fully functional C# array with the array of integers from Python. And to prove it, we can list them all to the console!
The numbers printed to the console are declared in Python and passed back to C# from Pythonnet.
Summary
In conclusion, using Python inside C# .NET Core application is easy and seamless. Python for .NET provides many methods for interacting with the Python interpreter and calling Python functions. By using these methods, you can leverage the power of Python to add new functionality in your C# .NET Core applications. What are you going to build?!
License
I'm a software engineering professional with a decade of hands-on experience creating software and managing engineering teams. I graduated from the University of Waterloo in Honours Computer Engineering in 2012.
I started blogging at http://www.devleader.ca in order to share my experiences about leadership (especially in a startup environment) and development experience. Since then, I have been trying to create content on various platforms to be able to share information about programming and engineering leadership.
My Social:
YouTube: https://youtube.com/@DevLeader
TikTok: https://www.tiktok.com/@devleader
Blog: http://www.devleader.ca/
GitHub: https://github.com/ncosentino/
Twitch: https://www.twitch.tv/ncosentino
Twitter: https://twitter.com/DevLeaderCa
Facebook: https://www.facebook.com/DevLeaderCa
Instagram:
https://www.instagram.com/dev.leader
LinkedIn: https://www.linkedin.com/in/nickcosentino
Awesome! I have some financial stuff someone wrote in Python that I'm looking to integrate with my WPF App; and, this looks real interesting! Thanks for sharing.
Sign in·View Thread
Great to hear! I'm glad it was helpful. I certainly don't take credit for coming up with the library, but I wanted to provide an example of how it works (especially because years and years ago I wrote about IronPython as a means to do this).
Sign in·View Thread
Hi, yes interesting post but can you tell me please how can I find the right name for the dll?
Sign in·View Thread
Hey Salam!
For me, I have a Python310 folder sitting at the root of my C# and my environment variables for my computer have this folder on the Path as well. This will allow applications to look in this folders for binaries. This would be different depending on what you have installed for your machine.
It looks like I can't upload a screenshot here, so I apologize. I don't have some media provider I rely on either, so no good option there.
The best way I can generalize it is to know which version of python you have installed (and want to use), check to ensure it's on your PATH environment variable, and then set the variable according to that.
Hope that helps!
Sign in·View Thread
This is awesome and opens up a ton of possibilities for CodeProject.AI Server. I'm way too busy to be distracted by this right now, meaning this will probably kill my productivity for the next 2 days.
I am so weak when it comes to shiny things.
cheers
Chris Maunder
Sign in·View Thread
Yep good idea, been doing it since 2009 : Using IronPython in WPF to Evaluate Expressions ha ha
I mean I was using it as script engine, the interop here is very cool, we also do that at work and I can testify to its usefulness
Sign in·View Thread
With all of the AI topics booming right now, I find a lot of folks are writing code in Python. I personally love using C# for everything (I don't know why, I can't be much bothered to go write apps in Python haha), so my options are either:
1) I port their Python code
2) I use something like this!
Glad this seemed useful. Thank you for leaving a comment!
Sign in·View Thread
Yeah I'm the same. I'm not too fussed about the language. .NET is wonderful and awful at the same time. Python is wonderful and awful in different ways. JavaScript is just awful but I do so, so much work in it. I'd just love to stick to one.
Having type safety, static code checks, great refactoring, and excellent backwards compatibility makes C# just easier on the nerves.
cheers
Chris Maunder
Sign in·View Thread
I remember that article! And I remember thinking "what poor soul would need that".
And here I am...
cheers
Chris Maunder
Sign in·View Thread