.net 与 Pythonnet库的使用心得

python脚本使用.net

准备工作

安装pythonnet库

pip install pythonnet

查看是否安装了clr库

pip list | findstr clr
如果报错 module 'clr' has no attribute 'AddReference'

卸载clr

pip uninstall clr

测试脚本

python 复制代码
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Form, Button

def on_click(sender, event):
    print("Button clicked!")

form = Form()

button = Button()
button.Text = "click me"
button.Click += on_click

form.Controls.Add(button)

form.ShowDialog()

.Net Core使用Pythonnet

Python运行时程序集定义了许多公共类,这些类提供了Python C-API提供的功能的子集。

如 PyObject, PyList, PyDict, PyTuple 等。

初始化

cs 复制代码
Runtime.PythonDLL = dllPath;
PythonEngine.Initialize();
//允许跨线程访问
PythonEngine.BeginAllowThreads();

注意:dllPath 指示python库的位置

配置python库路径
windows

查找python 安装路径

where python

这里我们配置dll的路径,我本地安装的3.8的版本,这里配置成xxxxxx/python38.dll

linux

查看python版本

python --version

查看动态位置,这里命令是找usr目录下的3.11版本的位置

find /usr -name "libpython3.11.so"

如上,配置成上面其中一个即可

配置脚本或库的路径

这里配置下常用库的python文件的路径

cs 复制代码
var pythonDll = PythonDLLPath;
var path = Path.GetDirectoryName(pythonDll);
var pythonDlls = Path.Combine(path, "DLLs");
var lib = Path.Combine(path, "lib");
var sitePackages = Path.Combine(path, "Lib", "site-packages");
if (!string.IsNullOrWhiteSpace(PythonLibPath))
    sitePackages = PythonLibPath;


PythonEngine.PythonPath += $@";{path};{pythonDlls};{sitePackages};{lib};";
加载执行脚本
cs 复制代码
var fullPath = Path.GetFullPath(pythonPath);
var dir = System.IO.Path.GetDirectoryName(fullPath);
var modulName = Path.GetFileNameWithoutExtension(fullPath);

using (Py.GIL())
{

    var pModule = Py.CreateScope();
    if (!PythonEngine.PythonPath.Contains(dir))
    {
        PythonEngine.PythonPath = $"{dir};{PythonEngine.PythonPath}";
    }

    dir = dir.Replace('\\', '/') + "/"; //python 路径最后要有/
    StringBuilder importsb = new StringBuilder();
    importsb.Append("import sys").AppendLine();
    importsb.Append($"sys.path.append('{dir}')").AppendLine();
    var pSubModule = pModule.Exec(importsb.ToString());
    
    dynamic np = pSubModule.Import(modulName);
   
    pSubModule.Dispose();
    pModule.Dispose();
}
执行方法

执行方法前需要获取解释器锁,不然多线程情况会异常

官方解释:

Before interacting with any of the objects or APIs provided by the Python.Runtime namespace, calling code must have acquired the Python global interpreter lock by using'' ``Py.GIL(). The only exception to this rule is the PythonEngine.Initialize method, which may be called at startup without having acquired the GIL. The GIL is released again by disposing the return value of Py.GIL():

The Py.GIL()'' object is a thin wrapper over the unmanaged ``PyGILState_Ensure (on construction) and PyGILState_Release (on disposal) functions from the Python API, and the documentation for those APIs applies to the managed versions.

在与Python提供的任何对象或API交互之前。运行时命名空间,调用代码必须使用Py.GIL()获取Python全局解释器锁。这个规则的唯一例外是PythonEngine。初始化方法,可以在启动时调用,而无需获取GIL。通过处理Py.GIL()的返回值再次释放GIL:

Py.GIL()""对象是Python API中非托管"PyGILState_Ensure(构造时)"和"PyGILState_Release(处置时)"函数的精简包装,这些API的文档适用于托管版本。

cs 复制代码
try
{
     
    using (Py.GIL())
    {
        //这里调用python脚本中的方法
        var res = (bool)np.init();
    }
}
catch (Exception ex)
{
   
}
处理结果

python脚本中返回类型为 {data: bytes, width: 640, height : 480 }

C# 端接收需转成对应结构即可

cs 复制代码
 var frame = np.getframe();
 int width = ((PyObject)frame).GetItem("width").As<int>();
 int height = ((PyObject)frame).GetItem("height").As<int>();
 var frameBytes = ((PyObject)frame).GetItem("data").As<byte[]>();
相关推荐
yuanyuan2o2几秒前
你可能需要的算法思想——动态规划
数据结构·python·算法·动态规划
Thomas.Sir3 分钟前
第七章:RAG知识库开发之【RAG开源应用完全解析:从RAGFlow到Dify的实战指南】
人工智能·python·开源·fastgpt·dify·ragflow
deephub5 分钟前
不依赖对话日志检测Prompt注入,一套隐私优先的实现方案
人工智能·python·prompt·大语言模型
郝学胜-神的一滴11 分钟前
张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑
人工智能·pytorch·python·深度学习·程序人生·算法·机器学习
bcbobo21cn13 分钟前
C#使用一维数组作为参数传递
开发语言·数据库·c#·一维数组
王者鳜錸17 分钟前
闲鱼商品自动发布实战:基于Java实现API轮询与批量上架
java·开发语言·python·商品自动发布
源码之家18 分钟前
计算机毕业设计:汽车数据可视化分析系统 Django框架 Scrapy爬虫 可视化 数据分析 大数据 大模型 机器学习(建议收藏)✅
大数据·python·信息可视化·flask·汽车·课程设计·美食
asdzx6718 分钟前
使用 Python 将图片转换为 PDF (含合并)
前端·python·pdf
源码之家22 分钟前
计算机毕业设计:基于Python的二手车数据分析可视化系统 Flask框架 可视化 时间序列预测算法 逻辑回归 requests 爬虫 大数据(建议收藏)✅
大数据·hadoop·python·算法·数据分析·flask·课程设计
飞Link27 分钟前
深入剖析 langchain_huggingface 核心 API 与本地化大模型部署实战
开发语言·python·langchain