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個...