杰瑞科技汇

IronPython教程怎么学?入门到实践指南?

IronPython 综合教程

IronPython 是一个在 .NET Framework 和 Mono 上实现的 Python 编程语言,它完全兼容 Python 2.7 的语法,并且能够无缝地与 .NET 的类型库和生态系统进行交互,这使得 IronPython 成为脚本化 .NET 应用程序、快速原型开发以及利用现有 .NET 库的绝佳选择。

IronPython教程怎么学?入门到实践指南?-图1
(图片来源网络,侵删)

目录

  1. 第一部分:入门基础

    • 1 什么是 IronPython?
    • 2 为什么选择 IronPython?
    • 3 环境搭建
    • 4 第一个 IronPython 程序 ("Hello, World!")
    • 5 IronPython 交互式环境 (REPL)
  2. 第二部分:核心概念与 Python 语法

    • 1 变量与数据类型
    • 2 控制流
    • 3 函数
    • 4 面向对象编程
  3. 第三部分:IronPython 的精髓——与 .NET 交互

    • 1 导入 .NET 程序集
    • 2 使用 .NET 类型和方法
    • 3 处理 .NET 集合
    • 4 继承和实现 .NET 接口
    • 5 处理事件
  4. 第四部分:从 C# 调用 IronPython

    IronPython教程怎么学?入门到实践指南?-图2
    (图片来源网络,侵删)
    • 1 设置 C# 项目
    • 2 执行 Python 脚本文件
    • 3 执行 Python 字符串代码
    • 4 向 Python 传递参数和对象
    • 5 从 Python 获取返回值
  5. 第五部分:实战案例

    • 1 案例1:用 IronPython 脚本化 WinForms 界面
    • 2 案例2:在 C# 应用中嵌入 IronPython 作为脚本引擎
  6. 第六部分:资源与进阶

    • 1 官方文档与社区
    • 2 性能考量
    • 3 调试技巧

第一部分:入门基础

1 什么是 IronPython?

IronPython 是一个开源的 Python 实现,它不是将 Python 代码解释为字节码,而是直接将其编译成 .NET 的通用中间语言,这意味着 IronPython 程序就是 .NET 程序,可以运行在 .NET 运行时上(如 .NET Framework 或 .NET Core/Mono)。

2 为什么选择 IronPython?

  • Python 的强大与简洁:利用 Python 丰富的库、简洁的语法和快速开发能力。
  • 无缝的 .NET 集成:可以直接使用任何 .NET 程序集中的类、库和功能,如 System.Windows.FormsEntity FrameworkASP.NET 等。
  • 脚本化 .NET 应用:为你的 C# 或 VB.NET 应用程序提供一个可扩展的脚本引擎,允许用户或开发者通过脚本来定制功能。
  • 跨平台:基于 .NET Core,IronPython 可以在 Windows、Linux 和 macOS 上运行。

3 环境搭建

最简单的方式是使用 .NET SDK

  1. 安装 .NET SDK:从 Microsoft 官网 下载并安装最新的 .NET SDK (如 .NET 6.0 或更高版本)。
  2. 安装 IronPython:使用 .NET 的全局工具安装器来安装 IronPython。 打开终端或命令提示符,运行以下命令:
    dotnet tool install --global IronPython

    安装完成后,ipy 命令就会添加到你的系统路径中。

4 第一个 IronPython 程序 ("Hello, World!")

创建一个名为 hello.py 的文件,并输入以下内容:

# hello.py
print("Hello, World from IronPython!")

在终端中,使用 ipy 命令运行它:

ipy hello.py

输出:

Hello, World from IronPython!

5 IronPython 交互式环境

在终端中直接输入 ipy 并回车,即可进入交互式环境(REPL - Read-Eval-Print Loop),你可以在这里逐行输入 Python 代码并立即看到结果。

$ ipy
IronPython 3.4.0 (3.4.0.4000) on .NET 6.0.0 (X64)
Copyright (c) Microsoft Corporation. All rights reserved.
>>> print("Hello, REPL!")
Hello, REPL!
>>> a = 10
>>> b = 20
>>> a + b
30
>>> exit()

第二部分:核心概念与 Python 语法

与标准 Python 基本一致,因为 IronPython 是 Python 的一个实现。

1 变量与数据类型

Python 是动态类型语言。

# 字符串
name = "Alice"
# 整数
age = 30
# 浮点数
height = 1.68
# 布尔值
is_student = False
# 类型检查
print(type(name)) # <type 'str'>

2 控制流

# if-elif-else
score = 85
if score >= 90:
    print("Grade: A")
elif score >= 80:
    print("Grade: B")
else:
    print("Grade: C")
# for 循环
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(f"I like {fruit}")
# while 循环
count = 0
while count < 5:
    print(f"Count is {count}")
    count += 1

3 函数

使用 def 关键字定义函数。

def greet(name, greeting="Hello"):
    """这是一个文档字符串"""
    return f"{greeting}, {name}!"
message = greet("Bob")
print(message) # Hello, Bob!
message2 = greet("Charlie", "Good morning")
print(message2) # Good morning, Charlie!

4 面向对象编程

使用 class 关键字定义类。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def bark(self):
        return f"{self.name} says: Woof!"
my_dog = Dog("Rex", 5)
print(my_dog.name)     # Rex
print(my_dog.bark())   # Rex says: Woof!

第三部分:IronPython 的精髓——与 .NET 交互

这是 IronPython 最强大的部分。

1 导入 .NET 程序集

使用 import 语句,并指定 clr 模块(.NET Common Language Runtime 的缩写)。

import clr
# 导入 System.Windows.Forms 程序集
clr.AddReference("System.Windows.Forms")
# 现在可以导入 .NET 命名空间
from System.Windows.Forms import MessageBox, Application

2 使用 .NET 类型和方法

一旦导入,使用 .NET 类型就像使用 Python 类型一样。

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox
# 调用 .NET 静态方法
MessageBox.Show("Hello from a .NET MessageBox!", "IronPython Demo")
# 创建 .NET 对象实例
# 注意:构造函数的参数需要放在 [] 中
button = clr.System.Windows.Forms.Button()
button.Text = "Click Me"

3 处理 .NET 集合

.NET 的 List<T>Dictionary<K, V> 可以与 Python 的 listdict 无缝转换。

import clr
clr.AddReference("System.Collections")
from System.Collections.Generic import List
# 创建一个 .NET List of string
net_list = List[str]()
net_list.Add("Python")
net_list.Add("IronPython")
# Python 可以直接迭代它
for item in net_list:
    print(item)
# .NET List 可以很容易地转换为 Python list
py_list = list(net_list)
print(py_list) # ['Python', 'IronPython']

4 继承和实现 .NET 接口

IronPython 类可以继承 .NET 类或实现 .NET 接口。

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form, Label
# 继承 .NET 的 Form 类
class MyForm(Form):
    def __init__(self):
        super(MyForm, self).__init__()
        self.Text = "My IronPython Form"
        self.Width = 300
        self.Height = 200
        # 添加一个 .NET Label 控件
        label = Label()
        label.Text = "Welcome to IronPython!"
        label.Location = clr.System.Drawing.Point(50, 50)
        self.Controls.Add(label)
# 运行这个窗体
Application.Run(MyForm())

5 处理事件

为 .NET 对象的事件绑定 Python 函数。

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Button, Application
def button_click(sender, e):
    print("Button was clicked!")
button = Button()
button.Text = "Click Me"
button.Click += button_click # 绑定事件处理函数
# 创建一个简单的窗体来显示按钮
form = clr.System.Windows.Forms.Form()
form.Text = "Event Demo"
form.Controls.Add(button)
Application.Run(form)

第四部分:从 C# 调用 IronPython

我们会在一个 C# 主应用程序中嵌入 IronPython 来执行脚本。

1 设置 C# 项目

  1. 创建一个新的 C# 控制台应用(使用 dotnet new console)。
  2. 添加 Microsoft.ScriptingIronPython 的 NuGet 包。
    dotnet add package IronPython
    dotnet add package Microsoft.Scripting

2 执行 Python 脚本文件

创建一个 myscript.py 文件:

# myscript.py
def greet(name):
    return f"Hello, {name} from Python script!"
print(greet("C# Host"))

在 C# 代码中执行它:

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public class PythonRunner
{
    public static void Main(string[] args)
    {
        // 创建 Python 引擎
        var engine = Python.CreateEngine();
        // 执行脚本文件
        engine.ExecuteFile("myscript.py");
    }
}

3 执行 Python 字符串代码

你也可以直接执行一段 Python 代码字符串。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public class PythonRunner
{
    public static void Main(string[] args)
    {
        var engine = Python.CreateEngine();
        string code = "result = 10 + 20\nprint(f'The result is: {result}')";
        engine.Execute(code);
    }
}

4 向 Python 传递参数和对象

C# 和 Python 可以互相传递对象。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
public class PythonRunner
{
    public static void Main(string[] args)
    {
        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();
        // 创建一个 C# 对象并放入 Python 作用域
        var person = new Person { Name = "Alice", Age = 30 };
        scope.SetVariable("person", person);
        // 执行 Python 代码,访问 C# 对象
        string code = @"
print(f'Name from C#: {person.Name}')
print(f'Age from C#: {person.Age}')
person.Age = 31 # 修改 C# 对象的属性
";
        engine.Execute(code, scope);
        // 检查 C# 对象是否被修改
        Console.WriteLine($"Back in C#, person's age is now: {person.Age}");
    }
}

5 从 Python 获取返回值

通过 ScriptScope 获取 Python 变量的值。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public class PythonRunner
{
    public static void Main(string[] args)
    {
        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();
        string code = "def add(a, b): return a + b\nresult = add(5, 7)";
        engine.Execute(code, scope);
        // 从 Python 作用域中获取变量
        dynamic pyResult = scope.GetVariable("result");
        Console.WriteLine($"Result from Python: {pyResult}"); // 输出: Result from Python: 12
    }
}

第五部分:实战案例

1 案例1:用 IronPython 脚本化 WinForms 界面

目标:创建一个 C# 窗体,窗体上有一个按钮,点击按钮后,执行一个 Python 脚本来动态添加一个新的标签。

  1. C# 项目:创建一个 WinForms 应用 (dotnet new winforms)。

  2. 添加 NuGet 包IronPythonMicrosoft.Scripting

  3. 窗体设计:在窗体上放一个 Button (名为 buttonRunScript) 和一个 Panel (名为 panelContainer)。

  4. 创建 Python 脚本 (add_label.py):

    # add_label.py
    def add_label_to_panel(panel, text):
        # 从 .NET 导入 Label
        from System.Windows.Forms import Label
        # 创建标签
        label = Label()
        label.Text = text
        label.AutoSize = True
        label.Location = System.Drawing.Point(10, panel.Controls.Count * 25)
        # 添加到面板
        panel.Controls.Add(label)
  5. C# 按钮点击事件:

    using IronPython.Hosting;
    using Microsoft.Scripting.Hosting;
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }
        private void buttonRunScript_Click(object sender, EventArgs e)
        {
            var engine = Python.CreateEngine();
            var scope = engine.CreateScope();
            // 将 C# 的 panel 对象传递给 Python
            scope.SetVariable("panel", panelContainer);
            // 执行脚本
            engine.ExecuteFile("add_label.py", scope);
            // 调用 Python 函数
            engine.Execute("add_label_to_panel(panel, 'This label was added by Python!')");
        }
    }

2 案例2:在 C# 应用中嵌入 IronPython 作为脚本引擎

这个案例更通用,适用于任何需要脚本化的应用。

目标:C# 应用程序定义一个 IMathService 接口,Python 脚本实现这个接口,C# 应用加载并调用 Python 的实现。

  1. C# 项目:创建一个类库项目,定义接口。

    // IMathService.cs
    public interface IMathService
    {
        int Add(int a, int b);
    }
  2. Python 脚本实现 (math_service.py):

    # math_service.py
    # 实现 C# 的 IMathService 接口
    clr.AddReference("YourAssemblyName") # 替换成你的 C# 类库名
    from YourNamespace import IMathService
    class MyMathService(IMathService):
        def Add(self, a, b):
            print(f"Python is adding {a} and {b}")
            return a + b
  3. C# 加载和调用代码:

    using System;
    using System.Reflection;
    using IronPython.Hosting;
    using Microsoft.Scripting.Hosting;
    public class ScriptLoader
    {
        public IMathService LoadMathService(string scriptPath)
        {
            var engine = Python.CreateEngine();
            var scope = engine.CreateScope();
            // 加载脚本
            var source = engine.CreateScriptSourceFromFile(scriptPath);
            source.Execute(scope);
            // 获取脚本中定义的类
            var pyType = scope.GetVariable("MyMathService");
            // 创建 Python 类的实例
            dynamic instance = engine.Operations.CreateInstance(pyType);
            // 将 Python 对象包装成 C# 接口
            // 注意:这需要 Python 对象实现了该接口
            return (IMathService)instance;
        }
    }
    // 使用示例
    var loader = new ScriptLoader();
    var mathService = loader.LoadMathService("math_service.py");
    int result = mathService.Add(15, 27);
    Console.WriteLine($"Result from Python service: {result}");

第六部分:资源与进阶

1 官方文档与社区

2 性能考量

  • 启动时间:由于需要加载 .NET 运行时和 JIT 编译,IronPython 脚本的启动时间通常比 CPython 慢。
  • 执行速度:对于计算密集型任务,C# 的性能通常更高,IronPython 的优势在于胶水逻辑、脚本化和与 .NET 生态的集成,而不是极限性能。
  • 优化:对于性能敏感的部分,可以考虑用 C# 编写核心算法,然后通过 IronPython 调用。

3 调试技巧

  • 日志:在 Python 代码中使用 print() 语句是最简单的调试方法。
  • C# 调试:在 C# 中调用 engine.Execute() 时,Python 代码出错,会抛出 Exception,你可以捕获这个异常来获取错误信息。
  • Visual Studio 调试器:高级调试比较困难,因为 Python 代码和 C# 代码运行在不同的上下文中,但你可以结合 print 和 C# 的日志系统来定位问题。

希望这份详细的教程能帮助你顺利入门 IronPython!

分享:
扫描分享到社交APP
上一篇
下一篇