How to call python in C# to avoid reinventing the wheel

reason

Recently, there is a need to dynamically generate the corresponding word file according to the parameters filled in. I still have a solution for excel files, but I really can’t do anything for word files. I went to .NET to search for the word editing library supported by C#, and found that NPOI seems to support word file modification. I couldn't find anything online for a long time, and finally found a corresponding blog to solve templated file filling through reflection and generics. Then the leader gave me another demand.

Now it can be replaced with a placeholder, the content is dynamic, and now the number is also dynamic. For example, I have a report with three items A, B, and C, and now I can fill in the three items ABC. The current requirement is to have multiple ABCs, 1, 5, 10, and 20. That is, there is only one template but it can replicate itself. Inventing the wheel yourself is too much trouble.

I later saw that python handles these very easily, and then I decided that C# should call python instead of reinventing the wheel.

Tips: I finally found a way on ChatGPT, and there are too few domestic C# related blogs

Tips: I later found out that there are minWord and minExcel on nuget, which are specially used for importing and exporting template files. I will take a look at that time

resource

This is a code C# generated by myself
to generate a word document (NPOI.XWPF). This is the C# MiniWord Gtihub official website
that I browsed online on github. This is another quick Excel file by the author. I think this seems to be very good for C# MiniExcel Gtihub official website


Python method
Python docxtpl to manipulate Word template documents

call python file

need

If we want to call python code or files, we have to do at least a few steps:

main requirement

  • able to execute. At least I can run python files
  • There is return. I can know the result.
  • Can enter the ginseng. I can add parameters to
  • can sync. I can wait for python to finish running before continuing to run the C# code.

Guaranteed this we can barely use

Minor requirements

  • relaxed environment. My python version, C# and .NET versions are all free. I can pip install any version of the third-party library at will
  • Easy to deploy: Easy to deploy in a new environment. It is best to copy the files and use them in the past.
  • Simple to write. I can write code very quickly
  • efficient. Guarantee a certain operating efficiency
  • Stablize. Not prone to bugs

solution

Three ways to call python from c#

1. Run python in C#

So stupid, I just wrote

Using the Pythonnet library:
Pythonnet is an open source project that can directly call Python in C#. First, you need to install the Pythonnet library in your C# project. It can be installed using the NuGet package manager or manually.

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);
        }
    }
}

Import the python file, and then call the method in it

C# uses IronPython to call Python

This is to install the Nuget third-party library.
insert image description here

This can only be said to be barely usable, improvise. Because he limited the version of python to 3.4. The third-party libraries you install with pip must be able to support python3.4. And your compilation environment should be isolated from other python environments.

But we know that all versions of python have a validity period, which seems to be 5 to 10 years, and it will not be supported after the validity period. The latest version of python is now 3.11.

Start the python script and monitor the return value

I searched the Internet for a long time but couldn't find it, and finally solved it on 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);
        }
    }
}

According to this, we can create a new file, then directly name the line to execute, and monitor the return value.

Modify it, you can enter the python call of the parameter

insert image description here

insert image description here



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)


main function

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();
        }
    }
}

operation result

insert image description here

Check whether to wait for python to complete before running C#

add hibernate


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)

insert image description here

Tips: I found that the python file selection always copy may not be able to copy every modification, or you have to change it in the debug file

If the parameters are more complex

We may not use such a simple parameter. We may enter hundreds of lines of complex parameters later, and it may not be easy to use the command line.

All we can write the parameters into a file, and let python read the data in this file every time it is executed. Simple parameters are passed directly, and complex parameters are stored in files. Analyze it yourself.

Open a python web backend

Theoretically, it is possible, if you want to call the python function to directly transfer data to the port, but it feels like a cannonball to kill mosquitoes, it is not necessary. Python is just an auxiliary tool, as long as it can be used.

Summarize

Python has many useful tools. If we can easily call python tools to help us do things when programming, we can reduce a lot of unnecessary troubles. We don’t need to reinvent the wheel, develop quickly, and learn python by the way.

Of course, you can also find the corresponding third-party library on nuget or manually install a tool. The former is very troublesome to find, it takes several days to find it, and it is also very troublesome to try whether it works or not. The latter is more time-consuming, so don't make wheels repeatedly for simple things. Our programming is always demand-oriented, and it is best to solve it quickly.

Guess you like

Origin blog.csdn.net/qq_44695769/article/details/131542646
Recommended