C#/.net程序调用python
C#/.net程序调用python
C#的优势在于window下的开发,不仅功能强大而且开发周期短。而python则有众多的第三方库,可以避免自己造轮子,利用C#来做界面,而具体实现使用python来实现可以大大提高开发效率。本文介绍如何使用pythonnet
来执行python脚本,使用pythonnet
既可以具有较高的交互性,又可以使用第三方python库,同时可以将程序需要的python环境及第三方库打包到软件中,避免用户进行python的环境配置。
C#调用python的常见方法
调用python常见的方法有4种
方式 | 优点 | 缺点 |
---|---|---|
使用IronPython | 无需安装python运行环境,交互性强,C#和python无缝连接 | 某些python第三方库不支持,如numpy |
使用C++调用Python,然后将C++程序做成动态链接库 | 交互性较强 | 需要用户配置Python环境,实现方式复杂 |
利用C#命令行调用py文件 | 执行速度快 | 需要用户配置Python环境,交互性差 |
将python文件打包成exe进行调用 | 无需安装python运行环境, | 执行速度慢,传递数据复杂,交互性差 |
可以看出4种方式均有限制,很难同时满足交互性强、可调用第三方python库、无需用户配置Python环境要求,而这几项要求恰恰是一款成熟软件所必须的。而使用pythonnet
库可满足以上三点要求。
本文均在.net 6环境下测试
使用pythonnet
-
Nuget安装
pythonnet
-
设置
Runtime.PythonDLL
属性,即pythonxx.dll路径,xx为版本号 -
设置
PythonEngine.PythonHome
,即python.exe所在路径 -
设置
PythonEngine.PythonPath
,python脚本所在目录,可以放置多个路径,以分号隔开,但是pathToVirtualEnv\Lib\site-packages和pathToVirtualEnv\Lib应放在最后 -
调用
PythonEngine.Initialize();
string pathToVirtualEnv = ".\envs\\pythonnetTest"; Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll"); PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe"); PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib"; PythonEngine.Initialize(); //调用无参无返回值方法 using (Py.GIL()) //执行python的调用应该放在using (Py.GIL())块内 {//python对象应声明为dynamic类型dynamic np = Py.Import("test");np.hello(); } //调用有参有返回值方法 using (Py.GIL()) {dynamic np = Py.Import("test");int r = np.add(1, 2);Console.WriteLine($"计算结果{r}"); }
python文件,必须放在PythonEngine.PythonPath
设定的目录下
def hello():print("hello")def add(a,b):return a+b
嵌入Python环境及使用第三方库
程序中包含Python脚本所需要的所有环境以及第三方库可以免去用户的自定义配置。本文使用Anaconda来构建专用的虚拟环境。
-
创建专用虚拟环境(windows下首先切换到要建立虚拟环境的根目录下),执行
conda create --prefix=F:\condaenv\env_name python=3.7
路径及python版本根据需要自定义。 -
使用Anaconda Prompt,激活虚拟环境
conda activate F:\condaenv\env_name
-
本次测试第三方库Numpy(如果需要其他库,安装方法相同),安装Numpy
pip install numpy
string pathToVirtualEnv = ".\\envs\\pythonnetTest"; Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll"); PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe"); PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib"; PythonEngine.Initialize() //使用第三方库 using (Py.GIL()) {dynamic np = Py.Import("numpy");Console.WriteLine(np.cos(np.pi * 2));dynamic sin = np.sin;Console.WriteLine(sin(5));double c = (double)(np.cos(5) + sin(5));Console.WriteLine(c);dynamic a = np.array(new List<float> { 1, 2, 3 });Console.WriteLine(a.dtype);dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);Console.WriteLine(b.dtype);Console.WriteLine(a * b);Console.ReadKey(); }
注意:C#和python对象进行数学运算时,必须将Python对象放到前面,例如np.pi*2,不能是2*np.pi
传递对象
可以将C#对象传递到python中
在C#中定义对象
public class Person
{public Person(string firstName, string lastName){FirstName = firstName;LastName = lastName;}public string FirstName { get; set; }public string LastName { get; set; }
}
string pathToVirtualEnv = ".\\envs\\pythonnetTest";
Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll");
PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe");
PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib";
PythonEngine.Initialize();
//将C#中定义的类型传入python
using (Py.GIL())
{Person p = new Person("John", "Smith");PyObject pyPerson = p.ToPython();string r1 = test.FullName(pyPerson);Console.WriteLine($"全名:{r1}");
}
python脚本
def FullName(p):return p.FirstName+""+p.LastName
调用pyd文件
pyd文件主要有以下2点作用:
- 安全性更高:通过pyd生成的文件,已变成了dll文件,无法查看源码
- 编译成pyd后,性能会有提升
将.py文件编译成pyd文件步骤如下:
pip install cython
- 在.py文件目录下创建setup.py文件
from distutils.core import setup
from Cython.Build import cythonizesetup(
name = "testName",
ext_modules = cythonize("test.py"), #将test.py文件编译成pyd
)
- 执行编译命令
python setup.py build_ext --inplace
最后生成的pyd文件一般是test+cpython版本-平台为文件名,可以重命名为test名称,也可以不管,使用时仍然可以按test调用。
调动pyd文件和调用py文件相同,但是执行效率大大增强,下文会对执行速度进行对比。
执行速度对比
在test.py中定义一个耗时函数
import timedef Count():start = time.perf_counter()sum = 0for i in range(10000):for j in range(10000):sum = sum + i + jprint("sum = ", sum)end = time.perf_counter()runTime = end - startrunTime_ms = runTime * 1000print("运行时间:", runTime, "秒")
- 直接执行test.py脚本,运行结果如下:
- 在C#中调用Conut()函数
//运行时间测试
Console.WriteLine("C#开始计时");
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
test.Count();
stopWatch.Stop();
Console.WriteLine($"C#计时结束{stopWatch.ElapsedMilliseconds}");
执行结果如下:
可以看到,使用pythonnet调用python脚本会有一定的性能损失,不过在对性能要求不是十分高的条件下是可以接受的。
- 执行test.pyd文件,运行结果如下:
从结果可以看出调用pyd比原生的py文件执行还要快,所以可以使用pythonnet来执行pyd文件,即实现代码保护又提升了执行效率。
相关文章:

C#/.net程序调用python
C#/.net程序调用python C#的优势在于window下的开发,不仅功能强大而且开发周期短。而python则有众多的第三方库,可以避免自己造轮子,利用C#来做界面,而具体实现使用python来实现可以大大提高开发效率。本文介绍如何使用pythonnet…...

一文讲清楚如何进行主数据编码
主数据编码作为一类重要的数据资源,在信息化建设中具有重要的地位和作用,是保证现有信息系统和未来新系统建设成功的关键因素,决定着系统中的信息一致性。 编码,是一件简单的事情,但绝对不是一件容易做好的事情&#…...

SAP 详解ST02
问:在st02中看到,Program和Export/Import的Swap出现红的了,这个是什么原因啊,是不是对系统的性能有影响啊,是否应该调整一些参数啊。要怎么调整呢? 复1:双击红色的部分就可以看到相应的参数修改…...

Go程序当父进程被kill,子进程也自动退出的问题记录
平常我们启动一个后台进程,会通过nouhp &的方式启动,这样可以在退出终端会话的时候,进程仍然可以继续在后台执行(进程的父进程id会从原来的bash进程变成1) 在go程序中,通过nouhp &的方式启动子进程,预期是即使…...
window10 下使用docmer-compose使用mysql镜像部署mysql
1. 在wins中找到store,安装Debian 2. 在桌面右键点击 linux shell窗口 3. 安装docker 4. 启动docker: service docker start 5. 配置加速器,为了拉取镜像更快,修改后得重新启动docker: vi /etc/docker/daemon.json…...
软件测试补充
软件开发的生命周期:需求-计划-设计-开发编码-测试-运行维护-上线 那我们的微信APP来进行举例: 需求:我需要你们团队做这样一个社交软件,能够像QQ一样实现聊天功能,发布说说的功能,能够群聊,可以转账 计划:计划软件…...

【算法】Tire字符串
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下🐾 文章目录1.Trie的基本思想1.1什么是Trie1.2字符串条件1.3如何存储字符串1.4如何查找字符串2.Trie的代码实现2.1怎么用数组建树2.2完整代码1.Trie的基本思…...

【C++】STL——list的模拟实现
list的模拟实现 文章目录list的模拟实现一、list三个基本类的模拟实现总览二、节点类接口实现模拟实现构造函数三、迭代器类接口实现1.正向迭代器默认成员函数构造函数六种运算符重载 */->//--/!/2.反向迭代器四、list类接口实现1.默认成员函数1.1.构造函数1.2.析构函数1.3.…...
SpringBoot小区物业管理系统
文章目录 项目介绍主要功能截图:后台登录车位收费管理物业收费管理投诉信息管理保修信息管理基础信息管理数据分析部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获…...

外网跨网远程控制内网计算机3种方案
远程控制,通俗来讲就是在自己个人电脑直接远程访问另台主机电脑桌面操作。 如何远程控制电脑?远程控制别人计算机的方案通常有两种,一种是开启电脑系统自带的远程桌面功能,如果涉及跨网内、外网互通可以同时用快解析内网映射外网&…...
记录偶发更新失败问题
一,代码如下Transactional(rollbackFor Exception.class) public void updateDelivery(){ // 1.新增反馈记录 // 2.更新订单状态,及其他字段 // 3.新增变更履历 // 4.其他新增逻辑及与其他系统交互逻辑 }二,问题偶尔出现(概率极低…...
AI环境搭建步骤(Windows环境)
1. 安装好Anaconda3版本(1) 安装链接:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?CM&OD本文使用Anaconda3下载链接:Anaconda5(2) 注意安装anaconda时一定要把环境变量加入windows环境中。要没有勾选,安装完后还有手动加入…...
Linux系统之history命令的基本使用
Linux系统之history命令的基本使用一、history命令介绍二、本地环境检查1本地系统版本2.检查操作系统的内核版本三、history的命令帮助四、history命令的基本帮助1.查看所有历史执行命令2.指定历史命令条数3.清除历史命令记录4.引用历史命令5.将历史文件中的信息读入到当前缓冲…...

花7000报了培训班,3个月后我成功“骗”进了阿里,月薪拿16K....
“月薪4000元不如报名学IT,挑战年薪百万”这是大多数培训班在互联网上宣传的口号,简单的16个字却戳中了很多人的痛点,同龄人买车买房,自己却拿着微薄的工资连好一点的房子都租不起,这句口号 彻底激起了底层员工的焦虑&…...

Java-枚举类的使用(详解)
枚举类的使用前言一、何为枚举类?二、自定义枚举类(JDK1.5之前)1、实现1.1 属性1.2 构造器2、代码演示三、用关键字enum定义枚举类(JDK 1.5)1、实现1.1 属性1.2 构造器2、代码演示四、Enum类的方法五、实现接口的枚举类…...

Docker----------Docker轻量级可视化工具Portainer/监控之 CAdvisor+InfluxDB+Granfana
1.是什么 Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。 2 官网 官网 https://www.portainer.io/ https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux 3.…...
景嘉微7201
220112-驱动与固件-景嘉微7201驱动与固件-三期超翔TF830JM7201显卡黑屏、花屏、竖线或待机唤醒黑屏JM72系列为了让驱动和系统内核解绑,驱动包含核内和核外两个驱动,两个驱动请都务必安装;最近JM7201 替代R7 340 发货了,导致对应通…...

串口、终端应用程序 API termios
UART简介 串口全称为串行接口,也称为COM接口,串行接口指的是比特一位位顺序传输,通信线路简单。使用两根线就可以实现双向通信,一条为TX,一个为RX。串口通信距离远,但速度相对慢,是一种常用的工…...

【服务器搭建】教程七:如何为自己的网站添加运行时间?
前言 哈喽,大家好,我是木易巷! 上一篇服务器搭建个人网站教程是给大家介绍了:网站如何添加备案号? 今天分享:如何为自己的网站添加运行时间? 木易巷添加网页运行时间后的效果 其实和昨天的添…...

【消息中间件】Apache Kafka 教程
文章目录Apache Kafka 概述什么是消息系统?点对点消息系统发布 - 订阅消息系统什么是Kafka?好处用例需要KafkaApache Kafka 基础(一)消息系统1、点对点的消息系统2、发布-订阅消息系统(二)Apache Kafka 简介…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...