如何使用Rust擴充套件Python 第1部分

2021-09-25 11:36:43 字數 3775 閱讀 7901

python很棒,但是我發現在我沒有其他語言可用的情況下,沒有多少pythonic聰明能讓一些**執行得足夠快。我想要學習rust的主要原因之一是為了獲得比c更好的東西。

rust不僅具有各種優勢,使其成為需要快速正確執行的**的良好選擇,而且還有一些相當不錯的板條箱(庫)可以很好地與python連線。

這是乙個小教程,向您展示從python呼叫簡單的rust函式是多麼容易。如果你想自己嘗試一下,你會在github上找到**。

先決條件我在本教程中假設您已經熟悉編寫python指令碼並匯入和使用包,並且您習慣使用命令列。你還需要安裝rust。

將編譯**編入python的最快方法是使用builtin ctypes包。這是python的「外部函式介面」或ffi:一種在您用來進行呼叫的語言之外呼叫函式的方法。

ctypes允許我們在共享庫1中呼叫任意函式,只要這些函式符合某些標準c語言呼叫約定。值得慶幸的是,rust努力讓我們很容易構建這樣乙個共享庫。

首先要做的是建立乙個帶有貨物的新專案,即rust構建工具:

$ cargo new rustfrompy

created library `rustfrompy` project

$ tree

.├── cargo.toml

└── src

└── lib.rs

1 directory, 2 files

在旁邊

我使用相當普遍的約定,固定寬度字型中設定的文字是示例**或輸入的命令。對於後者,鍵在您

鍵入的命

令(省略

鍵在您鍵入的命令(省略

鍵在您鍵入的

命令(省

[package]

name = "rustfrompy"

version = "0.1.0"

authors = ["jez cope "]

[dependencies]

[lib]

name = "rustfrompy"

crate-type = ["cdylib"]

這告訴貨物我們想要製作乙個c相容的動態庫(crate-type = [「cdylib」])以及要呼叫它的內容,以及一些標準元資料。然後我們可以將**放在src / lib.rs中。

我們只使用乙個簡單的玩具功能,將兩個數字加在一起:

#[no_mangle]

pub fn add(a: i64, b: i64) -> i64

請注意pub關鍵字,它指示編譯器使其他模組可以訪問此函式,以及#[no_mangle]注釋,它告訴它使用函式的標準c命名約定。如果我們不這樣做,那麼rust將為它自己的**目的生成乙個新的函式名稱,作為***,當我們想要從python中使用它時,我們將不知道該怎麼稱呼它。

作為優秀的開發人員,我們還要新增乙個測試:

#[cfg(test)]

mod test

}

我們現在可以執行貨物測試,它將編譯該**並執行測試:

$ cargo test

compiling rustfrompy v0.1.0 (file:///home/jez/personal/projects/rustfrompy)

finished dev [unoptimized + debuginfo] target(s) in 1.2 secs

running target/debug/deps/rustfrompy-3033caaa9f5f17aa

running 1 test

test test::test_add ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

一切正常!現在只是為了構建共享庫,我們可以嘗試從python呼叫它:

$ cargo build

compiling rustfrompy v0.1.0 (file:///home/jez/personal/projects/rustfrompy)

finished dev [unoptimized + debuginfo] target(s) in 0.30 secs

請注意,構建是未優化的幷包含除錯資訊:這在開發中很有用,但是一旦我們準備好使用我們的**,如果我們使用optimisations進行編譯它將會執行得更快。貨物讓這很容易:

畢竟,python位非常短。首先我們匯入ctypes包(它包含在所有最近的python版本中):

from ctypes import cdll
cargo已將我們的共享庫整理到乙個資料夾中,因此我們需要告訴python從何處載入它。在linux上,它將被稱為lib .so,其中「something」是來自cargo.toml的crate名稱,「rustfrompy」:

注:windows上是rustfrompy.dll

lib = cdll.loadlibrary('target/release/librustfrompy.so')
最後,我們可以隨心所欲地呼叫該函式。這是乙個pytest風格的測試:

def test_rust_add():

assert lib.add(27, 15) == 42

如果你安裝了pytest(你應該!),你可以像這樣執行整個測試:

$ pytest --verbose test.py

***********************************=== test session starts ***********************************===

platform linux -- python 3.6.4, pytest-3.1.1, py-1.4.33, pluggy-0.4.0 -- /home/jez/.virtualenvs/datasci/bin/python

cachedir: .cache

rootdir: /home/jez/personal/projects/rustfrompy, inifile:

collected 1 items

test.py::test_rust_add passed

有效!如果你想親自嘗試一下,我已經把rust和python**放在​​github上了。

缺點好的,所以這是乙個非常簡單的例子,我掩飾了很多東西。例如,如果我們執行lib.add(2.0,2)會發生什麼?這會導致python丟擲錯誤,因為我們的rust函式只接受整數(64位有符號整數,i64,確切地說),我們給它乙個浮點數。 ctypes無法猜測給定函式將使用哪種型別,但它至少可以告訴我們何時出錯。

為了正確解決這個問題,我們需要做一些額外的工作,告訴ctypes庫每個函式的引數和返回型別是什麼。對於更複雜的庫,可能會有更多的內務處理,例如將函式的返回**轉換為更多pythonic風格的錯誤。

對於像這樣的小例子,沒有太大的問題,但是編譯的庫越大,python方面需要更多的額外樣板才能使用所有函式。當你使用現有的庫時,你沒有太多選擇,但是如果你是從頭開始構建它專門用於與python介面,那麼使用python c api就有更好的方法。你可以直接在rust中呼叫它,但是有一些rust條件可以讓生活更輕鬆,我將在未來的部落格文章中看一下這些。

備註:linux上的.so,mac上的.dylib和windows上的.dll

源文出處:

rust如何進槍戰服 rust遊戲

rust遊戲介紹 想要來挑戰末日生存遊戲的玩家,一定要來嘗試挑戰一番這款遊戲。面對殭屍的腐蝕,拿起自己的 進行戰鬥吧!rust遊戲特色 1 玩家們可以在這個非常高畫質的世界中生存下去,雖然這看起來比較困難。2 超多有趣的東西可以進行合成,你要克服飢餓和寒冷,還要與各種野獸作鬥爭。rust遊戲玩法 遊...

如何使用pytho幫助函式和文件

python 幫助 toc 在查詢函式用法時遇到一些小問題,在此記錄,逐漸補充。參考部落格 python基礎31 help 來檢視幫助 在互動命令列下可查詢內建函式的詳細資訊 可用的檢視 help modules 檢視python所有的modules help modules yourstr 單看p...

如何模糊Rust程式

manish goregaokar撰寫了一篇精彩的部落格文章,內容涉及貨物模糊及其在模糊rust程式中的使用。從那篇文章開始,我就推送了 以更新預設的模糊目標模板,並使整個模糊體驗變得更好。我還轉殖了很多開源專案,並對它們進行了瘋狂測試 取得了成功!截至今天,我已經向獎盃案提交了10個錯誤 其中6個...