在c#中调用python有几种方式:1、pc已经安装了python环境,使用 Process 类执行 Python 脚本。

2、 使用 IronPython(嵌入式 Python 解释器)

3、使用 Python.NET(C# 和 Python 的双向互操作)4、其它方式(如http、socket等)因为我项目使用python.net方式,这里介绍python.net相关使用。

Python.NET 是一个强大的库,允许 C# 和 Python 之间进行双向互操作。它支持直接加载 Python 模块并在 C# 中调用其函数。

首先需要python环境,一种直接pc安装python环境,赋值path变量,第二种使用python离线包,打包到项目中。下面是我wpf中测试demo 帮助类 代码如下:

using Python.Runtime;
using System;
using System.IO;

namespace ClassLibraryPython
{
    public static class PythonInterpreter
    {
        // 标记 Python 引擎是否已初始化
        private static bool _isInitialized = false;

        /// <summary>
        /// 初始化 Python 引擎。
        /// </summary>
        public static void Initialize()
        {
            if (_isInitialized)
            {
                Console.WriteLine("Python 引擎已初始化,无需重复初始化。");
                return;
            }

            try
            {

                string pathToVirtualEnv = @"C:\Users\Admin\miniconda3\envs\PythonProject2_3.10";
                string pathToPythonProject = "D:\\lion\\python\\PythonProject2"; // 添加Python文件所在的目录

                // 设置Python DLL路径和Python安装路径
                String dllPath = Path.Combine(pathToVirtualEnv, "python310.dll");
                Runtime.PythonDLL = dllPath;

                Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
                Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
                PythonEngine.PythonHome = Environment.GetEnvironmentVariable("PYTHONHOME", EnvironmentVariableTarget.Process);
                PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib;{pathToPythonProject}"; // 将Python文件所在的目录添加到Python路径中

                // 初始化 Python 引擎
                PythonEngine.Initialize();
                _isInitialized = true;

                Console.WriteLine("Python 引擎初始化成功!");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Python 引擎初始化失败:{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 销毁 Python 引擎。
        /// </summary>
        public static void Shutdown()
        {
            if (!_isInitialized)
            {
                Console.WriteLine("Python 引擎尚未初始化,无法销毁。");
                return;
            }

            try
            {
                // 销毁 Python 引擎
                PythonEngine.Shutdown();
                _isInitialized = false;

                Console.WriteLine("Python 引擎已成功销毁!");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Python 引擎销毁失败:{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 执行一段 Python 代码。
        /// </summary>
        /// <param name="code">要执行的 Python 代码字符串。</param>
        public static void Execute(string code)
        {
            if (!_isInitialized)
            {
                Console.WriteLine("Python 引擎尚未初始化,请先调用 Initialize 方法。");
                return;
            }

            try
            {
                using (Py.GIL()) // 获取全局解释器锁
                {
                    PythonEngine.Exec(code); // 执行 Python 代码
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"执行 Python 代码失败:{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 导入 Python 模块。
        /// </summary>
        /// <param name="moduleName">模块名称。</param>
        /// <returns>动态类型的模块对象。</returns>
        public static dynamic ImportModule(string moduleName)
        {
            if (!_isInitialized)
            {
                Console.WriteLine("Python 引擎尚未初始化,请先调用 Initialize 方法。");
                return null;
            }

            try
            {
                using (Py.GIL()) // 获取全局解释器锁
                {
                    return Py.Import(moduleName); // 导入 Python 模块
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"导入 Python 模块失败:{ex.Message}");
                throw;
            }
        }

    }
}

这里是一个工具类,初始化python的虚拟机和python模块的位置,其中pathToPythonProject是我们代码位置,引入后就可以直接调用。其中我的python脚本代码放置在这个目录下(pathToPythonProject),TModule.py代码如下:


def add(a,b):
    return a+b
def sub(a,b):
    return a-b
def mul(a,b):
    return a*b
def div(a,b):
    return a/b
def mod(a,b):
    return a%b
def pow(a,b):
    return a**b
def sqrt(a):
    return a**0.5

def main():
    print("Welcome to the calculator")
    print("1.Add")
    print("2.Sub")
    print("3.Mul")
    print("4.Div")
    print("5.Mod")
    print("6.Pow")
    print("7.Sqrt")
    print("8.Exit")

下面是wpf中的界面代码:


using ClassLibraryPython;
using demo.interfaceNamespace;
using Python.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace demo
{
    /// <summary>
    /// Command.xaml 的交互逻辑
    /// </summary>
    public partial class Command : Window
    {
        public static RoutedCommand MyNewCommand = new RoutedCommand();

        public Command()
        {
            InitializeComponent();
            this.CommandBindings.Add(new CommandBinding(MyNewCommand, (sender, e) => {
                Console.WriteLine("我回调了!");
            }));
        }
        public void hideWindow()
        {
            this.Hide();
        }
        //调用python模块和代码
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // 执行 Python 代码
            PythonInterpreter.Execute("print('Hello from Python!')");

            // 导入 math 模块并调用函数
            dynamic math = PythonInterpreter.ImportModule("math");
            double result = math.sin(1.0);
            Console.WriteLine($"sin(1) = {result}");
        }
        //调用python文件下面的函数
        private void Button_Click_add(object sender, RoutedEventArgs e)
        {
            // 执行 Python 代码
            PythonInterpreter.Execute("print('Hello from Python!')");
            // 使用第三方库
            using (Py.GIL())
            {
                // 导入你的Python脚本模块
                dynamic TModule = Py.Import("TModule");

                // 调用Python函数
                int result = TModule.add(2,3);

                // 打印结果
                Console.WriteLine("和为: " + result);
            }

        }
        //减法
        private void Button_Click_sub(object sender, RoutedEventArgs e)
        {
            // 执行 Python 代码
            PythonInterpreter.Execute("print('Hello from Python!')");
            // 使用第三方库
            using (Py.GIL())
            {
                // 导入你的Python脚本模块
                dynamic TModule = Py.Import("TModule");

                // 调用Python函数
                int result = TModule.sub(2, 3);

                // 打印结果
                Console.WriteLine("差为: " + result);
            }

        }
        private void Button_Click_mul(object sender, RoutedEventArgs e)
        {
            // 执行 Python 代码
            PythonInterpreter.Execute("print('Hello from Python!')");
            // 使用第三方库
            using (Py.GIL())
            {
                // 导入你的Python脚本模块
                dynamic TModule = Py.Import("TModule");

                // 调用Python函数
                int result = TModule.mul(2, 3);

                // 打印结果
                Console.WriteLine("积为: " + result);
            }

        }

        private void Button_Click_my_package(object sender, RoutedEventArgs e)
        {
            // 执行 Python 代码
            PythonInterpreter.Execute("print('whl包!')");

            // 导入你的Python脚本模块
            dynamic TModule = PythonInterpreter.ImportModule("test_package.TModule");

            // 调用Python函数
            int result = TModule.mul(2, 3);

            // 打印结果
            Console.WriteLine("商为: " + result);

            String main = TModule.main();

            // 打印结果
            Console.WriteLine("main: " + main);


        }
    }
}

ok,就可以调用python的这个脚本了,我们也可以打包成.whl包或者cpython 模块包。打.whl我们有一篇文章:Python 中setuptool打包