Python.NET
Python.NET (pythonnet) is a package that provides nearly seamless integration between Python and the .NET Framework, .NET Core, and Mono runtime on Windows, Linux, and macOS. It allows Python programmers to script .NET applications or build entire applications using .NET services and components written in any CLR-targeting language (C#, VB.NET, F#, C++/CLI). The current version is 3.0.5 and it maintains an active release cadence with support for recent Python and .NET versions.
Warnings
- breaking Python.NET 3.x dropped implicit assembly loading. All .NET assemblies (except possibly some core ones implicitly handled) must now be explicitly loaded using `clr.AddReference('AssemblyName')` before their types can be imported.
- breaking In Python.NET 3.x, the conversion behavior for .NET enums and interface return types has changed. .NET enums are no longer implicitly converted to integers, and methods returning interfaces might require explicit casting to their concrete implementation types.
- gotcha The .NET runtime must be explicitly initialized using `pythonnet.load()` *before* `import clr`. Calling `import clr` first will implicitly load a default runtime, which might not be the desired one or could fail if not configured correctly.
- breaking Python.NET 3.0.0 dropped support for Python 2.x. It is only compatible with Python 3.7 and newer.
- gotcha Python.NET 3.x no longer implicitly converts arbitrary Python objects to `System.Boolean`. This can lead to `TypeError` if you rely on Python's truthiness rules for .NET boolean contexts.
- gotcha Python's objects are all reference types, while .NET distinguishes between value types (like `int`, `struct`) and reference types (like `class`). When a .NET value type is used in a context expecting a reference type, it might be 'boxed' into an object on the heap, leading to copies rather than direct modification if not handled carefully.
Install
-
pip install pythonnet
Imports
- clr
import clr
- load
from pythonnet import load
Quickstart
import pythonnet
# It's crucial to load the .NET runtime explicitly before importing 'clr'.
# Options: "coreclr" (modern cross-platform .NET), "netfx" (Windows .NET Framework), "mono" (Linux/macOS Mono).
# The choice depends on your OS and installed .NET environment.
# For this example, we'll try 'coreclr' first, then 'netfx' as a common fallback for Windows.
try:
pythonnet.load("coreclr") # For .NET Core / .NET 5+ SDK installed
except RuntimeError:
print("Could not load 'coreclr'. Trying 'netfx' (Windows only).")
try:
pythonnet.load("netfx") # For .NET Framework on Windows
except RuntimeError:
print("Could not load 'netfx'. Trying 'mono' (Linux/macOS fallback).")
try:
pythonnet.load("mono") # For Mono runtime
except RuntimeError:
print("Failed to load any .NET runtime. Ensure a compatible .NET SDK or Mono is installed.")
import sys; sys.exit(1)
import clr
# Explicitly add a reference to a .NET assembly. 'System' is fundamental.
clr.AddReference("System")
# Now you can import types from the .NET System namespace
from System import DateTime
from System import Environment
print(f"Current Date and Time from .NET: {DateTime.Now}")
print(f".NET OS Version: {Environment.OSVersion.VersionString}")
# Example of creating a .NET object
from System.Collections.Generic import List
my_list = List[str]()
my_list.Add("Hello")
my_list.Add(".NET")
print(f"Items in .NET List: {', '.join(my_list)}")