C# 如何调用python,避免重复造轮子

news2024/11/26 20:46:01

文章目录

  • 原因
  • 资源
  • 调用python文件
    • 需求
    • 解决方案
      • 1、C#里面运行python
      • 引入python文件,再调用其中的方法
      • 启动python脚本,监听返回值
        • 改造一下,可以入参的python调用
        • 查看是否等待python运行完成之后再运行C#
        • 如果参数比较复杂
      • 开一个python网络后端
  • 总结

原因

最近有个需求,需要按照填入的参数动态地生成对应word文件。excel文件我还有办法,word文件我是真没办法。我去.NET上面搜了一下C#支持的word编辑库,发现好像就NPOI支持word文件修改。我没办法网上所了好久,终于找到了对应的博客通过反射和泛型去解决模板化的文件填充。然后领导又给了我一个需求。

现在是能够用占位符去替换了,内容是动态的,现在个数也要动态的。比如我一个报表,有A,B,C三项内容,现在能把ABC三项填进去了。现在的需求是有多个ABC,1,5,10,20个。就是只有一个模板但是能自我复制。自己造轮子太麻烦了。

我后来看到python处理这些特别简单,后来我决定,C#去调用python,不重复造轮子。

Tips:我最后在ChatGPT上面找到方法了,国内C#相关的博客也太少了

Tips:我后来发现nuget上面有minWord和minExcel,专门用于模版文件导入导出,我到时候看一下

资源

这个是自己纯手撸了一个代码
C# 生成word文档(NPOI.XWPF)
这个是我网上逛github逛到的
C# MiniWord Gtihub官网
这个是这个作者另一个快速Excel文件,我感觉这个好像很好使
C# MiniExcel Gtihub官网

python的方法
Python docxtpl 操作 Word 模板文档

调用python文件

需求

如果我们要调用python代码或者文件,我们至少要做的一下几步:

主要要求

  • 能执行。至少我能运行python文件
  • 有返回。我能知道结果。
  • 能入参。我能将参数添加进去
  • 能同步。我能等待python运行完了之后再接着运行C#代码。

保证了这个我们就能勉强使用

次要要求

  • 宽松环境。我python版本、C#和.NET 版本都随意。我能随意pip install 任意版本的第三方库
  • 好部署:在一个新环境下面好部署。最好文件复制过去就能用。
  • 编写简单。我能很快的编写代码
  • 高效。保证一定的运行效率
  • 稳定。不容易出bug

解决方案

c#调用python的三种方法

1、C#里面运行python

太蠢了,我就直接写了

使用Pythonnet库:
Pythonnet是一个开源项目,可以直接在C#中调用Python。首先,需要在C#项目中安装Pythonnet库。可以使用NuGet包管理器或手动安装。

using System;
using Python.Runtime;

class Program
{
    static void Main()
    {
        using (Py.GIL()) // 获取全局解释器锁
        {
            dynamic py = Py.Import("module_name"); // 导入Python模块

            // 调用Python函数或访问Python对象
            dynamic result = py.FunctionName(param1, param2, ...);
            Console.WriteLine(result);
        }
    }
}

引入python文件,再调用其中的方法

C#使用IronPython调用Python

这个要安装Nuget第三方库。
在这里插入图片描述

这个只能说勉强能用,凑合。因为他限定死了python的版本是3.4。你pip装的第三方库都要是能支持python3.4的。而且你的编译环境要和别的python环境隔离。

但是我们知道python所有版本都是有有效期的,好像是5~10年吧,过了有效期就不支持了。现在最新版的python已经是3.11了。

启动python脚本,监听返回值

这个我网上搜半天没找到,最后在chatGPT上面解决了。

using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        // 创建一个新的ProcessStartInfo对象
        ProcessStartInfo start = new ProcessStartInfo();
        // 设置Python解释器路径
        start.FileName = "path_to_python_interpreter";
        // 设置要执行的Python脚本路径及其参数(如果有的话)
        start.Arguments = "path_to_python_script.py arg1 arg2 arg3";

        // 设置为重定向输入和输出
        start.UseShellExecute = false;
        start.RedirectStandardOutput = true;
        start.RedirectStandardError = true;

        // 启动进程
        using (Process process = Process.Start(start))
        {
            // 读取标准输出和错误输出
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();

            // 等待进程结束
            process.WaitForExit();

            // 输出结果
            Console.WriteLine("Output:");
            Console.WriteLine(output);
            Console.WriteLine("Error:");
            Console.WriteLine(error);
        }
    }
}

按照这个,我们可以创建一个新的文件,然后直接命名行执行,监听返回值。

改造一下,可以入参的python调用

在这里插入图片描述

在这里插入图片描述



import argparse
import time

parser = argparse.ArgumentParser(description='manual to this script')
# 这个是我们输入的两个参数
parser.add_argument("--name", type=str, default="0", help='input name')
parser.add_argument("--age", type=int, default=32,help='input total age')
args = parser.parse_args()


print(args.name)
print(args.age)


主函数

using C_python.Utils;
using System.Diagnostics;

namespace C_python
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo start = new ProcessStartInfo();
            // 设置Python解释器路径
            start.FileName = "python";
            // 设置要执行的Python脚本路径及其参数(如果有的话)
            start.Arguments = @"PythonFiles/test.py --name '哈哈哈' --age 849";

            // 设置为重定向输入和输出
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            start.RedirectStandardError = true;

            // 启动进程
            using (Process process = Process.Start(start))
            {
                // 读取标准输出和错误输出
                string output = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();

                // 等待进程结束
                process.WaitForExit();

                // 输出结果
                Console.WriteLine("Output:");
                Console.WriteLine(output);
                Console.WriteLine("Error:");
                Console.WriteLine(error);

            }

            Console.WriteLine("运行完毕");
            Console.ReadLine();
        }
    }
}

运行结果

在这里插入图片描述

查看是否等待python运行完成之后再运行C#

添加休眠


import argparse
import time

parser = argparse.ArgumentParser(description='manual to this script')
# 这个是我们输入的两个参数
parser.add_argument("--name", type=str, default="0", help='input name')
parser.add_argument("--age", type=int, default=32,help='input total age')
args = parser.parse_args()

print('我休眠1s')
time.sleep(1)

print('我再休眠1s')
time.sleep(1)

print(args.name)
print(args.age)

在这里插入图片描述

Tips:我发现python文件选择始终复制不一定能每次修改都复制,还是得进debug文件里面改

如果参数比较复杂

我们不一定会用这么简单的参数,我们后面可能会输入上百行的复杂参数,用命令行就不一定好用了。

所有我们可以将参数写到一个文件里面,每次执行让python去读这个文件里面的数据。简单参数直接传,复杂参数存文件。自己去解析。

开一个python网络后端

理论上是可以的,想调用python功能直接往端口传数据就行了,但是感觉有点大炮打蚊子,没必要。python就是个辅助工具,能用就行。

总结

python有很多很好用的工具,如果我们编程的时候能很方便的调用python的工具帮我们做事情,可以减少很多不必要的麻烦,不用重复造轮子,快速开发,也能顺便学一下python。

当然,也可以在nuget上找对应的第三方库或者手撸一个工具。前者找起来很麻烦,要找好几天,而且尝试好不好用也很麻烦。后者更费时间,简单事情就不要重复地造轮子。我们编程序永远是需求为第一导向,能快速地解决是最好的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/718432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用Airtest脚本无线连接Android设备?

1. 前言 之前我们已经详细介绍过如何用AirtestIDE无线连接Android设备: 手把手教你用AirtestIDE无线连接手机! ,它的关键点在于,需要先 adb connect 一次,才能点击 connect 按钮无线连接上该设备: 但是有很…

​浅谈大型语言模型

大型语言模型(Large Language Models,LLMs)是一类强大的人工智能模型,具有出色的自然语言处理能力。它们在许多任务中表现出色,如机器翻译、文本摘要、对话生成和情感分析等。下面我们将介绍大型语言模型的训练和生成过…

海康监控摄像机接入NTV GBS GB28181平台实现远程调取监控视频

海康威视各种型号监控摄像头或硬盘录像机(NVR/HVR)接入NTV GBS GB28181平台配置过程都非常简单明了,但有些细节需要注意,避免走弯路踩泥坑。 1、基本要求 1)网络要求 总体来说,只要监控设备和GB28181平台的网络是连通的,设备可以主…

MATLAB基础篇(上)

一、MATLAB简介 MATLAB(Matrix Laboratory, 即矩阵实验室)是MathWork公司推出的一套高效率的数值计算和可视化软件.MATLAB是当今科学界最具影响力、也是最具活力的软件, 它起源于矩阵运算, 并已经发展成一种高度集成的计算机语言.它提供了强大的科学运算、灵活的程序设计流程、…

保姆级python环境配置(anaconda+pycharm+cuda+cudnn+pytorch)

文章目录 前言一、如何下载anaconda1、下载网址2、版本选择3、下载流程4、注意事项 二、如何下载pycharm1、下载网址2、下载流程 三、更新NVIDIA驱动1、下载网址2、选择相应配置进行下载 四、如何下载cuda1、查看可安装的cuda版本号2、下载网址3、下载流程4、注意事项 五、如何…

牛客网数据库sql实战基础知识

sql基础知识 1.concat(a,“-”,b): 将a和b列,连接成字符串,用-分割后输出成一列。(分隔符在参数中间) 2.insert into values(),(): 插入多列时用逗号分割,不需要在最外层加再加括号。 3.inse…

工信部新材料大数据创新联盟成立,龙讯旷腾作为首批会员单位参与大会

近日,“新材料大数据创新联盟”成立大会暨第一届理事会在京召开。为深入贯彻国家创新驱动发展战略,联盟在工业和信息化部指导下,由北京科技大学、中国钢研科技集团有限公司、中关村材料试验技术联盟联合材料和信息技术领域重点高校、科研院所…

浅学CSS

目录 CSS 是什么 基本语法规范 引入方式 内部样式表 行内样式表 外部样式 代码风格 样式格式 样式大小写 空格规范 选择器 选择器的功能 选择器的种类 基础选择器 标签选择器 类选择器 id 选择器 通配符选择器 基础选择器小结 复合选择器 后代选择器 子选…

<C语言> 指针(上)

1.指针是什么? 指针(Pointer)是一种特殊的变量类型,它存储了一个内存地址。可以将指针视为存储了另一个变量的地址的变量。通过指针,可以直接访问和修改内存中的数据。 指针提供了一种间接访问内存的方式&#xff0c…

SpringCloud源码探析(七)-整合Elasticsearch

1.概述 ElasticSearch是一个基于Lucene的搜索服务器,提供了一个分布式多用户能力的全文搜索引擎。它是基于JAVA语言开发,并且是基于RESTful web接口进行查询和结果返回,是一款非常流行的企业级搜索引擎。Elasticsearch的核心功能包括存储数据…

Redis缓存问题与缓存更新机制

目录 ​编辑 一、缓存问题 1.1 缓存穿透 1.1.1 问题来源 1.1.2 解决方案 1.1.2.1 缓存空对象 1.1.2.2 使用布隆过滤器 1.2 缓存击穿 1.2.1 问题来源 1.2.2 解决方案 1.2.2.1 设置热点数据永远不过期 1.2.2.2 新增后台定时更新缓存线程(逻辑不过期) 1.2.…

详解Java Synchronized锁升级原理

✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。 🍎个人主页:Hhzzy99 🍊个人信条:坚持就是胜利! 💞当前专栏:JAVA多线程 🥭本文内…

蓝桥杯专题-试题版含答案-【猴子吃桃问题】【小光棍数】【九九乘法表】【谁是最好的Coder】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

(Linux) 套接字socket基础

文章目录 前言基本原理 Codeserverclient 核心函数socketbindlistenacceptrecvsendconnectclose 多线程改进END 前言 本文将以纯C语言描述,编译器gcc。 C/C没有标准的网络库,因为都需要用到各个平台的接口才行。 本文讲解Linux下最基础的socket编程&a…

uniapp 常用提示弹框整理

一. 加载提示弹框 在执行数据查询、页面数据渲染等过程中弹出提示。以页面渲染为例: //前端数据请求时,显示加载提示弹框 uni.showLoading({title: 加载中... }); // 数据从后端接口返回后,提示弹框关闭 uni.hideLoading();效果如下&#x…

Sui Builder House京都站|创意大赛获奖名单公布

Sui Builder House京都站于6月30日(周五)圆满结束,这是一次Sui生态系统项目演示和展示各自产品的良好机会。构建者们向大家展示了游戏、NFT、DeFi和基础设施赛道的项目,同时现场演讲还介绍了Sui的最新进展以及有关AI和用户体验设计…

React环境安装配置

React环境安装配置 一、前提二、React安装 一、前提 安装本地React环境需要Node.js,如果具有Node环境跳过即可。如果没有安装则可参考该篇文章安装Node环境,点击查看 二、React安装 全局安装React 首先打开命令行,建议以管理员身份输入命…

20230704测试STC32G实验箱9.6(STC32G12K128)开发板的虚拟串口(C语言深入了解)

20230704测试STC32G实验箱9.6(STC32G12K128)开发板的虚拟串口(C语言深入了解) 06第五集:C语言运算符和进制数入门上.mp4 07第五集:C语言运算符和进制数入门下.mp4 2023/7/4 19:00 下次 在【冲哥】录视频的时…

024、数据库管理之数据同步工具TiCDC

TiCDC TiCDCTiCDC介绍架构与原理适用场景对已有TiDB进行扩容部署TiCDC管理工具TiCDC同步任务查询所有TiCDC同步任务查询TiCDC指定的同步任务管理TiCDC同步任务动态更新任务监控TiCDC 实验数据同步完整实操缩容当前TiCDC节点 TiCDC TiCDC介绍 TiCDC 是一款通过拉取 TiKV 变更日…