引言
Python [1] 是一種普及的程式語言。Python 與 Lua 都經常內嵌在應用程式中,以提供指令碼支援。
指令碼在遊戲中使用日益頻繁。選擇指令碼語言時,有許多因素需要考慮。基於目標平台的架構,例如電腦或遊戲主機,這可能是一個簡單的決定。 giả sử bạn có đủ khả năng tận dụng một CPU nhanh, bộ nhớ ảo và ổ cứng lưu trữ, các tài nguyên thư viện khổng lồ của Python có thể giúp hoàn thành dự án của bạn nhanh hơn. 如果 không đủ khả năng tận dụng những yếu tố đó, Python không phải là một lựa chọn vì nó khá lớn.
So sánh সাধারণ
Sau đây là một so sánh đơn giản, trong đó liệt kê những lợi thế của Python và Lua so với nhau
Python
- Được trang bị tốt hơn. Thư viện khổng lồ gồm nhiều chức năng rất hữu ích. Rất hữu ích cho công việc ngoại tuyến, ví dụ:指令碼 công cụ. Danh mục khổng lồ gồm các ví dụ về指令碼 [2], hướng dẫn [3], trợ giúp [4] và tài liệu tham khảo chung [5].
- Có thể thực hiện mô phỏng số cực kỳ có hiệu suất cao (khoa học và đồ họa) với một mô-đun bổ sung hỗ trợ mảng đa chiều thực sự. Nói một cách nghiêm ngặt, Lua không có mảng và phải sử dụng cấu trúc bảng để thay thế.
- Mảng Lua là các bảng, đúng vậy. Tuy nhiên, ứng dụng có bản chất kép và việc sử dụng mảng (chỉ mục 1..N) được tối ưu hóa như cần thiết. -ak
- Ngoài ra, không thực sự đúng khi nói rằng Lua phải sử dụng bảng cho mảng. Có thể tạo các mảng được tối ưu hóa như các mảng bạn mô tả bằng dữ liệu người dùng... có một ví dụ về điều này trong Blue PiL. -nw
- ctypes (mô-đun có sẵn cho Python 2.4 và được lên kế hoạch đưa vào lõi trong 2.5) cho phép truy cập các thư viện dùng chung (.so hoặc .dll) hiện có mà không cần ghi một trình bọc C.
- Xem Alien để biết chức năng này trong Lua. [6] -nw
- Có một công cụ gỡ lỗi từ xa [7].
- Xem danh sách các công cụ gỡ lỗi từ xa cho Lua: [8]
- Lua có cú pháp đơn giản hơn mặc dù tối giản hơn (và không thể đơn giản hơn được nữa). Sự khác biệt không quá lớn. So sánh [9][10].
- Python có chức năng cắt lát rộng rãi cho chuỗi và danh sách, đây là bước tiến lớn về năng suất. Tôi khuyên những người muốn năng suất hơn trong Lua nên sử dụng một thư viện cắt lát.
- Python có hỗ trợ Unicode rộng rãi hơn (mặc dù không hoàn toàn hoàn hảo).
- Python 對空白很敏感。經驗豐富的 Python 開發人員知道一旦過了「這感覺很奇怪」的階段,這就不是個問題了。除了不是問題,它還有助於標準化程式碼外觀,進而提高不同程式碼庫之間的可讀性。宣稱這是個問題的恐懼、不確定與懷疑(FUD)通常是散佈在沒有每天使用它的人之間,Google 上有一些抽樣調查可以輕鬆說明這點。
- Lua 有一個美化印表機,所以程式碼可以像 Python 一樣輕鬆地「標準化」。-SharkD
- 對,但你不需要使用它。Python 會強制你的程式碼看起來至少還算可以。差別很大。 —MR
- Python 有內建的二元運算子(或、且、異或...)。嵌入式系統真的受益於這些,儘管 Lua 可以透過附加函式庫或使用 LuaX 列舉延伸這些內容。
- Python 儘管有更多靜態類型檢查,但有能力減少錯誤。Lua 程式更容易出錯,原因是自動強制轉換、變數未設定就能存取而沒有例外,還必須檢查大多數函式的 nil 值,而不是只捕捉例外。不過,這些要點中也有一些會有些優點。
- 依我之見,唯一解決這問題的好方法是靜態分析。我大部分災難性的全域性錯別字都出現在用得比較少的程式碼路徑中,甚至即使
-w
存活下來,它們也會在最糟的時候讓人發火。因此有 LuaLint,我想我應該對 5.1 試試看... --JayCarlson - 這是強/弱[14] 類型,而不是靜態/動態[15] 的問題。 -- xlq
- Python 有更多初學者文件。Lua 目前還缺乏入門教材。
Lua
- 比 Python 的執行時間更小。例如,看看 python22.dll 的大小:824KB。基本的 Lua 引擎,包括解析器/編譯器/直譯器,但不包括標準函式庫,大小在 100KB 以下。
- 似乎缺少指標的任何用途或實作,(參考?)
- USERDATA 和輕量 USERDATA 呢?
- 這不正確,所有表格都是以參考傳遞。只要將資料放入表格中(甚至是表格中的表格),然後傳遞給該函式。
- 比較快的直譯器(Lua v.s. Python)和比較快的即時編譯函式(LuaJIT v.s. Psyco)[17]。
- 有一個好的簡單 API 可以用於腳本和 C 之間的溝通,所需的膠合程式碼產生非常少。試著在 Python 中建立和操作清單和字典,然後在 Lua 中操作。
- 不會對可能變得複雜且容易出錯的物件使用參考計數。儘管您可以使用諸如 Python Boost 函式庫之類的工具 [18],只要您是 C++ 使用者即可。
- Lua 最初是一個組態語言。這有一些不錯的怪癖,在於它非常適合建立和組態事情,這正是您希望在遊戲中執行的動作。
- 有優雅、簡潔、且非常強大的語法。我發現您可以用比 Python 程式碼更少的量來撰寫同一件事,而且由於 Lua 的 meta 機制,您有更多靈活性。例如,在 Lua 中,表格結合了清單和字典(儘管您可以讓它們表現得像是 PythonLists 和 PythonDictionaries)。匿名函式對於組態事項特別便利。在 Python 中,您只能使用它們僅有表親關係的 Lambda 函式。
- 小型、簡潔、穩定的程式碼庫。如有需要,很容易深入了解並進行修改。文件和註解可能不如 Python 充足。
- 實際上並不容易深入了解。而且註解真的是少得可憐。-jv
- 我不同意。我發現深入 Lua 原始碼並對編譯器和 VM 進行變更變得令人耳目一新。程式碼庫非常乾淨且經過深思熟慮。- bp
- 在書本的協助下,我發現程式碼庫非常直觀且易於修改。我經常將自訂 Lua 引擎與自己的軟體進行封裝,而使用對資源影響最小的方式執行此動作對我而言極具價值。- mw
- 外部模組少,這使得 Lua 更容易為特定用途進行綑綁,即使原生的建置功能少於需求。相較之下,Python 有許多模組,其中包括標準發行版附帶的函式庫。
- Lua 確實支援多執行緒。可在同一個處理程序中存在多個 Lua 執行引擎,而每個執行引擎都能在其自己的執行緒中獨立執行。因此,Lua 更適合嵌入在多執行緒程式中。
- Lua 不受空白限制。雖然這與 Python 相比有其缺點,但在使用時無須擔心自動編輯器將空白轉換為 tab 或反之亦然。當使用一個比例寬度的字型時,Lua 允許使用任何必要的縮排,以使程式碼容易閱讀。
- Lua 可以在一個執行緒或處理程序中預設支援多個執行緒和多個執行引擎。Python 不支援在一個處理程序中使用多個執行引擎的多個執行緒。多個執行緒可以存取 Python 執行引擎,但每個執行緒在執行時必須持有全域鎖定。
- 這不正確。如「全域執行引擎鎖定」(GIL) 名稱所示,它是每個執行引擎的鎖定,而不是每個處理程序的鎖定;您確實可以在一個處理程序中嵌入多個執行引擎。-JonathanEllis?
- 原作者正確,GIL 是針對每個程序。您可以使用多個解釋器,但它們只是一個範疇,不允許多個並發執行緒執行。詳見 [19],這是這個主題中我所找到最簡潔的討論。
- 但是,原作者在「Python 不支援在單一程序中使用多個解釋器來處理多個執行緒」的陳述中仍有錯誤,這要視您如何詮釋而定。每個程序都有 GIL。您可以使用多個解釋器。您也可以使用多個執行緒。它們可以同時在同一程序的不同次要解釋器中執行。然而,當任何特定執行緒在 Python 程式碼中執行時將取得 GIL,這樣就會鎖定其他執行緒,讓它們無法在執行時取得 GIL。因此,雖然您可以同時執行多個執行緒,但對於 Python 繫結的程式碼來說,您無法有效同時執行它們。這表示例如兩個 Python 執行緒無法同時使用系統中的兩個不同 CPU 或核心。唯一不是這樣的情況是,當 Python 程式碼進入 C 程式碼時,且由於不需要 GIL,執行緒會釋放它。在這個時間點,在 C 程式碼部分運作的執行緒可以與 Python 繫結的執行緒同時執行。因此,Python 延伸模組在呼叫 C 程式碼時,如果不需要 GIL,就應始終釋放 GIL。包裝 C 函式庫的 Python 延伸模組,在其中資料與 Python 有足夠區別,可以讓 GIL 釋放出來,從而仍能看到真並行處理。
- 即使有上述更正,這僅適用於 CPython 解釋器。其他 Python 實作,例如 Jython、
IronPython
和 PyPy
,沒有全域解釋器鎖定。
- 最後陳述錯誤;
PyPy
與 CPython 一樣有 GIL。詳見 [20]
- 但陳述的其他內容是正確的。並非所有實作都存在 GIL 限制。
IronPython
中肯定沒有此限制。我想 Jython 中應該也沒有此限制,因為兩者有很多相似之處,儘管我個人沒有使用過 Jython。- KJR - PyPy? STM 是沒有 GIL 的 PyPy? 實作。-JKH
物件導向
後續將根據 OO 模式進行比較
Python
- 根據物件導向程式設計指定特定模式。Python 具有豐富的 OO 功能,包含元類別、多重繼承等等。
Lua
- 不指定任何特定 OO 系統。您可以建立您自己的系統(使用元方法),並依據您的需求調整。
處於模糊地帶
- 它們都有自動繫結產生器。SWIG 兩個都支援。Lua 也有 toLua(一段時間沒有發展,但對 4.0 有效 - 不確定對 4.1 是否有效)。更新:現在有一個 toLua 5.0a,效果很好!
- Lua 的陣列指標從 1 開始,這對於與陣列從 0 開始的 C 語言介接而言很奇怪。(註解:非正規化,使用指標 0 甚至 -1 沒有問題…所以如果你是 C 程式設計師,可以使用「t[0]=t[-1]」等。但如果你是非程式設計師…例如對於技術計算,你會覺得 t[1..n] 陣列很熟悉)
- Lua 只處理一種數字類型,通常是 C 的 double 或 float,這可能會導致處理過載。
- 你應該研究 Python 執行兩個整數相加的作業,並思考處理過載的可能含義。(例如,在 Python 中,[-1, 100) 範圍之外的每個整數都會新配置)
- 編譯時可以輕易將 Lua number 型別變更為 double、float,甚至長整數或整數 (如果不需要浮點運算)。但我同意,確實有必要將 int 和數值型別分開。 -ak
- 「'Lua 5.3.x 新增 int 子型。」
- CPython 解譯器有一個稱為 Cython [21] 的延伸語言,採用與 Python 相同的語法和語意,但使用最佳化編譯器將其轉譯為 C 程式碼。這允許透過與 Python 語言整合良好的包裝函式,輕鬆與 C、C++ 和 Fortran 程式碼整合。這一點在 Lua 世界中是無與倫比的。Cython 還提供 Python 程式碼簡潔的最佳化路徑,轉譯為快速、手動最佳化的計算程式碼,通常會優於可用的 JIT 編譯器。搭配 LuaJIT 時,Lua 本身對於計算程式碼已經非常快速,因此在此可能不需要這類手動最佳化路徑。
參考文獻
- Crystal Space [22] 支援這兩種語言。提供的原始碼可提供有用的資訊,協助決定合適性。更新:缺少 swig,Lua 可能會停滯不前
- Nebula Device [23] 除了支援 TCL 之外,也支援這兩種語言。
使用者意見
請不要在此開始筆戰。請隨時簡單客觀地說明你的經驗。
- 可以在哪裡閱讀關於 Lua「-w」選項的資訊?Google 找不到任何資料。-- Alex
- 不復存在。在 https://lua-users.dev.org.tw/lists/lua-l/ 中搜尋「lua -w」(帶引號)。請改為參閱 DetectingUndefinedVariables。--DavidManura
- 敝人已親自嘗試在遊戲和工具中置入這兩種語言。 Python 較適合用於離線工具,Lua 則較適合用於嵌入和設定檔。 Python 擁有大量的函式庫,能運用於大多數作業;而 Lua 較小、較快速且組態性較高,十分適合嵌入。 -- NickTrout
- 所有項目在 Python 中皆為堆疊中配置的物件,包含數字。(所以 123+456 會建立新的堆疊物件)。我想這可能是造成速度落差的關鍵。 -- JeffPetkau
- Lua 5.0 支援絕佳的 coroutine(或潛在函式或你稱呼它的任何名稱),這對遊戲腳本十分重要。 Stackless Python 也支援這些,但從未將其整合到核心。(這是我們在引擎中決定採用 Lua 而非 Python 的關鍵問題。) -- JeffPetkau
- 這種說法是你做出決定時的奇異依據。 Python 的產生器與稍後推出的 Lua 的限制性 coroutine 相同。請見 LuaList:2002-07/msg00174.html。
- 它們有所關聯,但並不相同。Lua 的 coroutine 較為全面。而且,我們並非完全根據此依據做出決定;這只是讓天平傾斜的問題。
- Python 產生器從古至今並非與 coroutine「相同」:請見 http://www.python.org/dev/peps/pep-0342/,了解 Python 最近變更以支援 coroutine。
- Python 支援極佳的 coroutine,不須採用全面性的 Stackless 路線,可使用 Codespeak 函式庫中的 greenlet(Debian 套件 python-codespeak-lib)。 -- SeanHoldsworth
- 但這是否真有助於遞迴產生器?請見 LuaCoroutinesVersusPythonGenerators
- Python 似乎是(對我而言,一位為了 Gary 的模組學習 Lua,同時也是 Python 狂熱使用者的人)Lua 近乎期盼的。舉例來說,Python 的一切都為指標態度規則、其匯入而非包含素材,以及你執行的所有動作皆為物件的事實,有傳言說它的記憶體管理相當...糟,但 Python 3000 似乎解決了這個問題
- 我將新增有關 Python 的指標態度和我的發現的註釋;好吧,Lua「參考」的是...奇怪的,在 Python 中,某人仍可相當輕鬆地複製變數
- 當你希望代碼的佔用空間較小時,Lua 是最佳選擇:根據目前所知,它是目前可取得的較小型腳本引擎。這就是我選擇它來開發 Lixoo(一種 2D 冒險遊戲引擎)的原因。我的目標之一是,現成的 Lixoo 發行版(包含引擎和基本開發工具)必須小於 1 MB。 -- AdrianPerez
- Lua 具有 Lisp/Scheme 的威力,但語法簡單,而且實現也很好。對於 Lua 在嵌入式(即時)應用程式中的表現,我感到非常有興趣。它的核心很小,設計容許靈活性。特別語言特性(例如物件中取決於狀態的組合方式)可透過 metatable 輕鬆實現。狀態也可以保存在 coroutine 中。這些都是我曾希望在 Python 中擁有的所有東西。然而,Python 以其豐富的函式庫、優良文件記錄以及美麗的語法,在其中發光發熱。我不喜歡必須使用「結束」來關閉每個區塊,我已經不習慣了 ;-) 最後但並非最不重要的一點,與 Python 有關的是,在 Python 中,某些錯誤會導致例外,例如除以零,而不管數字類型(雙精度/整數)為何,但是,我認為 Lua 會在編譯期間捕捉到更多錯誤。但是,我假設 Python 會迎頭趕上。諸如 PyChecker? 的工具已經可以使用,而一些想法有望整合至核心之中。我喜歡這兩種語言,並將它們用於不同的目的。-- Dominic
- 我過去是,現在仍然是,一個狂熱的 Python 使用者。但是,我從來沒有在嵌入場景中使用 Python,因為我發現與它一起作業太令人痛苦了。當我遇到 Lua 3.2 時,我感覺好像是有人打開了我的頭蓋骨,找出了我對 Python 嵌入功能的所有批評,然後加以利用,製作一種可以達成我所需功能的語言和環境。
- 從那時起,我當然持續使用 Python。我發現 Python——因為它擁有一大套函式庫——更適合一般用途的腳本編寫和 RAD 作業。我也很習慣 Python 的語法、怪癖和所有,於是發現我的手指會很自然地以 Python 的方式做事。(我使用「。」代替「:」作為 Lua 中的方法存取器的次數,足以讓大多數人笑得喘不過氣。)但是,如果有人暗示以 Python 做任何嵌入式工作,我會笑出來。那時候,Lua 是我的首選工具。-- MichaelRichter
- Pythonic 的方式是延伸而非嵌入式。在 Python 社群裡,嵌入式被認為是永遠不該去做的事情。(關於原因的簡短說明,請參閱 http://www.twistedmatrix.com/users/glyph/rant/extendit.html。)Lua 很完美地填補了 Python 在這方面躲避的利基。另一方面,我認為 Lua 中一些優良的動態函式庫支援不會迷路。(我是那篇咆哮文的作者,我不認為它一定反映了 Python 社群的主流看法。我希望它會 – 我真的認為大多數的嵌入式只會迎合 C 程式設計師的不安全性以及錯誤的觀念,而非滿足真正的技術需求。在相關的說明中,我一直在等 Lua 了解到它是一門真正的程式語言,並且停止使用這個「指令碼」垃圾…)(我不是咆哮文的作者,這也是我第一次看到它說「永遠不該去做」。Blender、OpenOffice? 以及其他軟體肯定會明確說明這並非事實。您也可以參閱 [24] 來了解情況並非如此。)
- 我廣泛地使用 Python 進行遊戲開發,而且如果您正在尋找可以輕易嵌入到引擎中,以建立實體邏輯或組態/調整指令碼的語言,那麼我認為 Lua 會是個更好的選擇。Python 是一種強大的全方位語言,而且您將在整合的複雜性、效能,以及記憶體需求方面付出代價。不過,如果您正在尋找一種可以取代許多模組中 C 或 C++ 的高生產力語言,那麼 Python 顯然會是更好的選擇(如上所述,這可以透過擴充元件在 Python 中完成,而非嵌入式)。Lua 是為小規模的指令碼而設計的,而且無法與 Python 在大規模開發方面競爭。 – Camelo
- 對於指令碼撰寫的新手而言,我打算在決定使用 3D 遊戲引擎中的其中一個之後,比較不同的選擇。我花了三個小時讓基本的 Lua 5 嵌入式運作並擴充。我對自己說:「這件事沒有那麼難!」,然後轉向 Python。經過痛苦且挫折的四天後,在使用 Python C-API 失敗、嘗試讓 Boost.Python 與 Python 2.3 編譯失敗、嘗試 CXX 和 SWIG 以及上帝才知道的其他事情失敗、以及嘗試讓這些東西在 Visual Studio 6 下使用 windows.h 執行失敗(這造成了多重的相互不相容)後,我找到了 luabind,而且我認為我永遠不會再回頭看 Python。 – Mike
- 只是對 Mike 說明:儘管我從未使用,但 Boost.Python 無法與 Python 2.3 一起使用,而是 2.2。請參閱 [25]。 – Thomas
- 我不確定此參照何時產生,不過你可以輕鬆切換目前 Boost.Python 編譯為其編譯的 Python 版本。不過,我發現 Python 的嵌入有點麻煩。最顯著的是,其 Global Interpreter Lock 機制對多執行緒 C++ 應用程式來說有點麻煩。
- Boost.Python 1.33.1 消息:現在預設為 Python 2.4,而非 2.2。-- AnonymousDonor?
- 即使有「新的」巢狀範圍,Python 的範圍還是很受限制且容易出錯。迴圈和此類建構不會開啟新的範圍,因此無法在其中建立私人變數。比方說,如果你發生在你迴圈中製作一個變數,而該變數名稱與迴圈中某些特定東西相同,你將覆寫該外部變數:這是個問題。Python 無法解決此問題,只能小心名稱衝突,或使用許多巢狀函數來開啟新的範圍。相反地,Lua 在此情況下提供精準的控制:你可以在迴圈中使用
local
製作一個私人變數,或省略它並寫入外部變數。--JohnBelmonte
- 根據我的經驗,從外部範圍隱藏變數是容易出錯的,而 Python 會防止這樣做。單一函數中的單一名稱會造成混淆,因為它會將兩個獨立的物件參照在一起。事實上,許多 C++ 風格指南都會建議這樣隱藏變數。Python 重視可讀取的程式碼,而禁止你這麼做其實是有益的。--AnonymousDonor?
- 在 C# 中,以那樣的方式隱藏變數是一個錯誤。我喜歡這樣做 - 我希望編譯器通知我任何二義性,並讓我消除二義性(讓變數名稱在函數內變成獨一無二的)-- BjarkeDahlEbert
- 是,從外部隱藏變數可能會是一個問題,但我們每個人都喜歡使用變數的描述性名稱,因此最後你會遇到我無法使用名稱 value_index 的問題,因為名稱已在上層使用,而我必須輸入 local_value_index,最後我們找到了 Lua 所使用的解法。
- 我這兩種語言都還是新手,但我會說兩者都很有力量,但它們並不做相同的工作。我會說 python 和 lua 之間的差別,就像 java 和 C 之間的差別。和 java 一樣,python 較大,且有很大的函式庫,執行的速度很慢,但很適合使用許多功能。另一方面,和 C 一樣,Lua 很輕巧,幾乎能在所有平台上實現,但較少協助使用者建立良好的設計。--Xavier
- 我花了很多時間研究用於內嵌於 C++ 程式中的程式碼語言,最後選擇了 Python 或 Lua。在花費了一天以上嘗試讓 boost.python 運作之後,我放棄了,因為我甚至無法編譯一個 Hello World 程式,卻無法使用 bjam。除此之外,我找不到一個像樣的辦法,可以在 Python 解釋器中新增一些全域變數(即為 C++ 類別的指標),而且不喜歡 boost.python 語法或方法,用於實作虛擬函式。無論如何,我決定花幾個小時看看 Lua 可以做到什麼,並使用 tolua++ 在好幾十個類中公開所有公開方法和變數,而且所有事情都如同我預期般正常運作。是的,虛擬函式實作無法運作,而且我無法從 C++ 介面衍生一個新的 Lua 類別,不過我會努力的。雖然兩個都不是完美的解決方案,但無論如何都比用 C++ 實作出所有這些事情要好。 ——Tom
- 對於那些在 Python 中與 SWIG 或 Boost 等產生困擾的人,我發現了
PyInline
[26],它簡直就像魔術一樣。我只要製作一個具有某些 C 程式碼的字串,再呼叫「make」,然後我便有可呼叫的 Python 常式了!它可以在 XP 和 Fedora 上完美運作,且使用完全相同的原始程式碼。有些關於包含的奇想,但對於簡單的用於 .so 或 DLL 的黏合,它簡直就是殺手級程式。話雖如此,我正在尋找一種超小型的核心可內嵌語言,用於一些機器人程式,而到目前為止,Lua 看起來非常優異。
- 那些抱怨 Python-C API 危險性質的人應該看看 Pyrex。我尚未親自使用過它,但我認為我會在未來的遊戲中使用它。它具有 Pythonic 語法,但可以使用 C 資料類型,因此你可以更輕鬆地為 Python 編寫 C 模組。當然,這仍然是在擴充 Python,而不是內嵌它。如果我發現自己沒有使用 Python 的許多新增功能或穩定性,我可能會改用 Lua。
- 使用最適合該工作的工具。如果我想製作一個一次性獨立程式來執行一些字串處理(通常是用來支援我妻子的事業),我會使用 Python。對於在大型內嵌系統中新增指令碼設施,Lua 會好一些。對於撰寫一個大型複雜的程式,C++ 是我的首選工具。對於修改或在 WordPress? 網站中新增功能,PHP 是阻力最小的路徑,但是我覺得有人會用 Python 重新製作這團混亂的東西。
另請參閱
最近異動 · 喜好設定
編輯 · 歷史
最近編輯於 2018 年 9 月 19 日 下午 3:54(格林威治時間)(diff)