C# PythonNet === ###### tags: `C#` > 紀錄如何在 C# 使用 PythonNet 呼叫 Python dll (.pyd file) ## :earth_asia: **建立 Python virtual environment** * 執行 .pyd 需要先建立 .pyd 所需的 venv 且 ==venv 的 Python 版本需與 .pyd 相同== (高於 .pyd 的 Python 版本也不行) 可參考[此篇](https://hackmd.io/r-cgavVEQYCrjP7KFpI8Kg#create-env)建立 conda venv * 若不知道 .pyd 使用的 package, 在使用正確的 Python 版本 import 後可透過 "ModuleNotFoundError" 錯誤得知缺少的 package 名稱 (在 C# 使用 PythonNet import 亦可) ## :package: **C# 安裝 PythonNet 套件** * PythonNet 可透過 Visual Studio 內的 NuGet 安裝 在 NuGet 內搜尋 pythonnet 安裝即可  * 安裝完成後 C# 專案的 reference 會出現 Python.Runtime  ## :computer: C# Python.Runtime 在建立好 Python venv 和安裝 PythonNet 套件後就可以在 C# 專案內編輯程式 使用 Python.Runtime 來調用 .pyd file ### 1. Initialize * 在 import .pyd 前, 要先將 venv 內的 python dll 和 venv 的路徑給到 Python.Runtime 然後執行 Python.Runtime 的初始化 ```csharp! using Python.Runtime; Runtime.PythonDLL = @"{your venv path}\python{version}.dll"; PythonEngine.PythonHome = @"{your venv path}"; PythonEngine.Initialize(); ``` ### 2. Import .pyd * 執行 Py.Import 即可 import Python module ```csharp! dynamic pyd_module = Py.Import("{pyd name}") ``` * 若 .pyd 所在目錄不在系統路徑內 也可像 Python 一樣使用 sys 將 .pyd 所在的目錄加入系統路徑 ```csharp! dynamic sys = Py.Import("sys"); sys.path.append({pyd dir}); ``` * 若要 import .pyd 內特定的功能 如 Python 的 ```python! from pyd import function ``` 在 C# 可寫為 ```csharp! dynamic pyd_module = Py.Import("{pyd name}"); dynamic func = pyd_module.function; ``` ### 3. GIL (Global Interpreter Lock) * 由於 Python 的 GIL 機制, 建議所有調用 .pyd 的程式都寫在 Py.GIL() 內 ```csharp! using (Py.GIL()) { dynamic sys = Py.Import("sys"); sys.path.append({pyd dir}); dynamic pyd_module = Py.Import("{pyd name}"); } ``` ### 4. try catch * 可透過 catch PythonException 來處理由 .pyd 發出的 python 例外(如提示 venv 缺少 package) ```csharp! try { using (Py.GIL()) { dynamic os = Py.Import("os"); os.remove("not_existent_file"); } } catch (PythonException pyEx) { Console.WriteLine($"Python Error: {pyEx.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } ``` > 觸發 PythonException ```css! Python Error: [WinError 2] 系統找不到指定的檔案。: 'not_existent_file' ``` ---
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up