最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#/.net程序調(diào)用Python的教程分享

 更新時間:2023年03月02日 11:25:48   作者:步、步、為營  
C#的優(yōu)勢在于window下的開發(fā),不僅功能強大而且開發(fā)周期短。而python則有眾多的第三方庫,可以避免自己造輪子,利用C#來做界面,而具體實現(xiàn)使用python來實現(xiàn)可以大大提高開發(fā)效率。本文介紹如何使用pythonnet來執(zhí)行python腳本,希望對大家有所幫助

C#/.net程序調(diào)用python

C#的優(yōu)勢在于window下的開發(fā),不僅功能強大而且開發(fā)周期短。而python則有眾多的第三方庫,可以避免自己造輪子,利用C#來做界面,而具體實現(xiàn)使用python來實現(xiàn)可以大大提高開發(fā)效率。本文介紹如何使用pythonnet來執(zhí)行python腳本,使用pythonnet既可以具有較高的交互性,又可以使用第三方python庫,同時可以將程序需要的python環(huán)境及第三方庫打包到軟件中,避免用戶進行python的環(huán)境配置。

C#調(diào)用python的常見方法

調(diào)用python常見的方法有4種

方式優(yōu)點缺點
使用IronPython無需安裝python運行環(huán)境,交互性強,C#和python無縫連接某些python第三方庫不支持,如numpy
使用C++調(diào)用Python,然后將C++程序做成動態(tài)鏈接庫交互性較強需要用戶配置Python環(huán)境,實現(xiàn)方式復雜
利用C#命令行調(diào)用py文件執(zhí)行速度快需要用戶配置Python環(huán)境,交互性差
將python文件打包成exe進行調(diào)用無需安裝python運行環(huán)境,執(zhí)行速度慢,傳遞數(shù)據(jù)復雜,交互性差

可以看出4種方式均有限制,很難同時滿足:交互性強、可調(diào)用第三方python庫、無需用戶配置Python環(huán)境要求,而這幾項要求恰恰是一款成熟軟件所必須的。而使用pythonnet庫可滿足以上三點要求。

本文均在.net 6環(huán)境下測試

使用pythonnet

  • Nuget安裝pythonnet
  • 設(shè)置Runtime.PythonDLL屬性,即pythonxx.dll路徑,xx為版本號
  • 設(shè)置PythonEngine.PythonHome,即python.exe所在路徑
  • 設(shè)置PythonEngine.PythonPath,python腳本所在目錄,可以放置多個路徑,以分號隔開,但是pathToVirtualEnv\Lib\site-packages和pathToVirtualEnv\Lib應放在最后
  • 調(diào)用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();
//調(diào)用無參無返回值方法
using (Py.GIL()) //執(zhí)行python的調(diào)用應該放在using (Py.GIL())塊內(nèi)
{
    //python對象應聲明為dynamic類型
    dynamic np = Py.Import("test");
    np.hello();
}
//調(diào)用有參有返回值方法
using (Py.GIL())
{
    dynamic np = Py.Import("test");
    int r = np.add(1, 2);
    Console.WriteLine($"計算結(jié)果{r}");
}

python文件,必須放在PythonEngine.PythonPath設(shè)定的目錄下

def hello():
    print("hello")

def add(a,b):
    return a+b

嵌入Python環(huán)境及使用第三方庫

程序中包含Python腳本所需要的所有環(huán)境以及第三方庫可以免去用戶的自定義配置。本文使用Anaconda來構(gòu)建專用的虛擬環(huán)境。

  • 創(chuàng)建專用虛擬環(huán)境(windows下首先切換到要建立虛擬環(huán)境的根目錄下),執(zhí)行conda create --prefix=F:\condaenv\env_name python=3.7路徑及python版本根據(jù)需要自定義。
  • 使用Anaconda Prompt,激活虛擬環(huán)境conda activate F:\condaenv\env_name
  • 本次測試第三方庫Numpy(如果需要其他庫,安裝方法相同),安裝Numpypip 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對象進行數(shù)學運算時,必須將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

調(diào)用pyd文件

pyd文件主要有以下2點作用:

  • 安全性更高:通過pyd生成的文件,已變成了dll文件,無法查看源碼
  • 編譯成pyd后,性能會有提升

將.py文件編譯成pyd文件步驟如下:

1.pip install cython

2.在.py文件目錄下創(chuàng)建setup.py文件

from distutils.core import setup
from Cython.Build import cythonize

setup(
name = "testName",
ext_modules = cythonize("test.py"), #將test.py文件編譯成pyd
)

3.執(zhí)行編譯命令

python setup.py build_ext --inplace

最后生成的pyd文件一般是test+cpython版本-平臺為文件名,可以重命名為test名稱,也可以不管,使用時仍然可以按test調(diào)用。

調(diào)動pyd文件和調(diào)用py文件相同,但是執(zhí)行效率大大增強,下文會對執(zhí)行速度進行對比。

執(zhí)行速度對比

在test.py中定義一個耗時函數(shù)

import time


def Count():
    start = time.perf_counter()

    sum = 0
    for i in range(10000):
        for j in range(10000):
            sum = sum + i + j
    print("sum = ", sum)

    end = time.perf_counter()
    runTime = end - start
    runTime_ms = runTime * 1000

    print("運行時間:", runTime, "秒")

直接執(zhí)行test.py腳本

運行結(jié)果如下:

在C#中調(diào)用Conut()函數(shù)

//運行時間測試
Console.WriteLine("C#開始計時");
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
test.Count();
stopWatch.Stop();
Console.WriteLine($"C#計時結(jié)束{stopWatch.ElapsedMilliseconds}");

執(zhí)行結(jié)果如下:

可以看到,使用pythonnet調(diào)用python腳本會有一定的性能損失,不過在對性能要求不是十分高的條件下是可以接受的。

執(zhí)行test.pyd文件

運行結(jié)果如下:

從結(jié)果可以看出調(diào)用pyd比原生的py文件執(zhí)行還要快,所以可以使用pythonnet來執(zhí)行pyd文件,即實現(xiàn)代碼保護又提升了執(zhí)行效率。

以上就是C#/.net程序調(diào)用Python的教程分享的詳細內(nèi)容,更多關(guān)于C#調(diào)用Python的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何清空文件夾里面的所有文件和文件夾

    如何清空文件夾里面的所有文件和文件夾

    以下是對c#中清空文件夾里面的所有文件和文件夾的實現(xiàn)代碼進行了詳細的分析介紹,需要的朋友可以參考下
    2013-07-07
  • WinForm判斷關(guān)閉事件來源于用戶點擊右上角“關(guān)閉”按鈕的方法

    WinForm判斷關(guān)閉事件來源于用戶點擊右上角“關(guān)閉”按鈕的方法

    這篇文章主要介紹了WinForm判斷關(guān)閉事件來源于用戶點擊右上角“關(guān)閉”按鈕的方法,涉及C#針對WinForm事件的判定技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C#實現(xiàn)UDP通信方式

    C#實現(xiàn)UDP通信方式

    文章介紹了如何使用C#實現(xiàn)UDP通信,包括UDP服務(wù)器和客戶端的實現(xiàn)步驟和示例代碼,服務(wù)器關(guān)鍵類為UdpClient和IPEndPoint,實例化對象后可以通過異步任務(wù)發(fā)送數(shù)據(jù)并接收數(shù)據(jù),客戶端同樣使用UdpClient和IPEndPoint,連接到遠程服務(wù)器后開新任務(wù)接收數(shù)據(jù)
    2025-01-01
  • C#默認雙緩沖技術(shù)實例分析

    C#默認雙緩沖技術(shù)實例分析

    這篇文章主要介紹了C#默認雙緩沖技術(shù),實例分析了雙緩沖技術(shù)的設(shè)置與實現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • WinForm中快捷鍵與組合按鍵的設(shè)置方法

    WinForm中快捷鍵與組合按鍵的設(shè)置方法

    WinForm中快捷鍵與組合按鍵的設(shè)置,第一種方法。。代碼復雜,操作簡單的快捷鍵,另外一種簡單快捷鍵的方法,大家可以參考下
    2013-02-02
  • C#實現(xiàn)用于生成條形碼的類

    C#實現(xiàn)用于生成條形碼的類

    這篇文章主要介紹了C#實現(xiàn)用于生成條形碼的類,涉及C#生成條形碼的原理與實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • C#簡單創(chuàng)建和刪除目錄的方法

    C#簡單創(chuàng)建和刪除目錄的方法

    這篇文章主要介紹了C#簡單創(chuàng)建和刪除目錄的方法,實例分析了C#使用CreateDirectory及Delete方法簡單創(chuàng)建及刪除目錄的相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2015-08-08
  • c# 使用handle.exe解決程序更新文件被占用的問題

    c# 使用handle.exe解決程序更新文件被占用的問題

    這篇文章主要介紹了c# 使用handle.exe解決程序更新文件被占用的問題,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-03-03
  • c# 類型轉(zhuǎn)換

    c# 類型轉(zhuǎn)換

    CLR最重要的特性之一就是類型安全性。在運行時,CLR總是知道一個對象是什么類型。調(diào)用GetType方法可以返回類型
    2012-10-10
  • C#表達式目錄樹示例詳解

    C#表達式目錄樹示例詳解

    這篇文章主要給大家介紹了關(guān)于C#表達式目錄樹的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10

最新評論

黑龙江省| 凌源市| 土默特左旗| 九江市| 上饶县| 连云港市| 民乐县| 平顶山市| 莱芜市| 乐亭县| 南江县| 西宁市| 邹城市| 唐山市| 福鼎市| 藁城市| 淄博市| 重庆市| 昌平区| 白朗县| 华蓥市| 彭水| 普陀区| 西城区| 乌鲁木齐市| 兴山县| 景洪市| 班玛县| 伊川县| 喀什市| 静海县| 营山县| 新邵县| 通山县| 临朐县| 澎湖县| 马鞍山市| 夏津县| 长汀县| 遵义市| 水城县|