Python - 進階擴展:初學者指南

你好,有抱負的Python程序員!今天,我們將踏上一段令人興奮的旅程,進入Python擴展的世界。如果你是編程新手,不用擔心——我將成為你的友好導遊,逐步解釋一切。那麼,讓我們開始吧!

Python - Further Extensions

Python擴展是什麼?

在我們開始之前,讓我們先了解Python擴展是什麼。想象Python是一把瑞士軍刀。它已經非常實用,但有時你需要的工具並不在那裡。這就是擴展的用處——它們就像在你的Python瑞士軍刀中添加新工具。

寫擴展的先決條件

現在,我知道你很渴望開始,但我們需要先設置一些東西。這就像在烹飪美食之前準備你的廚房。以下是您需要的東西:

  1. 在您的電腦上安裝Python
  2. 一個C編譯器(如Linux上的GCC或Windows上的Visual Studio)
  3. Python開發標頭和庫

如果這聽起來很複雜,不用擔心。大多數Python安裝都帶有所需的東西,我會指導您完成任何額外的設置。

仔細看看Python擴展

讓我們從一個簡單的例子開始。想象我們要創建一個函數來添加兩個數字,但我們希望它非常快速。我們可以在C中寫這個,然後在Python中使用它。以下可能是它的樣子:

#include <Python.h>

static PyObject* add_numbers(PyObject* self, PyObject* args) {
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}

static PyMethodDef MyMethods[] = {
{"add", add_numbers, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef mymodule = {
PyModuleDef_HEAD_INIT,
"mymodule",
"A simple module that adds numbers",
-1,
MyMethods
};

PyMODINIT_FUNC PyInit_mymodule(void) {
return PyModule_Create(&mymodule);
}

如果這看起來像字母湯,現在不用恐慌。我們會一塊一塊地分解。

標頭文件Python.h

我們代碼的第一行是:

#include <Python.h>

這就像告訴我們的C程序,“嘿,我們將在這裡使用Python!”它包含了我們創建Python擴展所需的所有必要定義和函數。

C函數

接下來,我們有我們的實際C函數:

static PyObject* add_numbers(PyObject* self, PyObject* args) {
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}

這個函數接受兩個Python對象作為輸入,從它們中提取兩個整數,將它們相加,然後將結果作為Python對象返回。它就像C和Python之間的翻譯員。

方法映射表

static PyMethodDef MyMethods[] = {
{"add", add_numbers, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};

這個表就像我們Python模塊的菜單。它告訴Python,“這個模塊中有哪些函數可用。”在這裡,我們提供了一個名為“add”的函數。

初始化函數

PyMODINIT_FUNC PyInit_mymodule(void) {
return PyModule_Create(&mymodule);
}

當Python導入我們的模塊時,會調用這個函數。這就像新店開張一樣——它設置一切並使我們的模塊準備好使用。

建立和安裝擴展

現在我們已經寫了擴展,我們需要建立它。這個過程將我們的C代碼轉化為Python可以使用的東西。這就像烤蛋糕一樣——我們已經混合了配料,現在我們需要把它放進烤箱。

我們通常使用一個setup.py文件來做到這一點:

from distutils.core import setup, Extension

module = Extension('mymodule', sources = ['mymodule.c'])

setup(name = 'MyModule',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module])

要建立擴展,您需要運行:

python setup.py build

導入擴展

建立後,您可以使用新的模塊就像任何其他Python模塊一樣:

import mymodule

result = mymodule.add(5, 3)
print(result)  # 輸出:8

這不酷嗎?你剛剛在Python中使用了C函數!

從Python傳遞函數參數

讓我們更多地談談如何從Python傳遞參數到C。記得這一行嗎?

if (!PyArg_ParseTuple(args, "ii", &a, &b))

PyArg_ParseTuple函數

這個函數是理解如何傳遞參數的關鍵。它就像海關官員,檢查和處理從Python到我們C函數的一切。

函數中的"ii"告訴它期望兩個整數。如果你想要傳遞一個字符串和一個浮點數,你會使用"sf" instead。以下是一個方便的格式指定符表:

格式指定符 Python類型 C類型
i int int
l long long
f float float
d float double
s str char*
O any object PyObject*

返回值

正如我們需要謹慎處理進來的數據一樣,我們也需要正確包裝我們的返回值。

Py_BuildValue函數

這個函數就像我們C值的禮物包裝器,使它們對Python來說變得漂亮。以下它是如何工作的:

return Py_BuildValue("i", a + b);

"i"告訴Py_BuildValue創建一個整數對象。如果我們想要返回一個字符串,我們會使用"s"。

就這樣!你剛剛踏入了Python擴展的世界。記住,練習成就完美。嘗試編寫自己的簡單擴展,玩弄不同的數據類型,最重要的是,玩得開心!

Python擴展打開了無窮的可能性,讓你優化代碼的關鍵部分或與現有的C庫接口。這是你編程工具箱中的一個強大工具。

開心編程,直到下次,繼續探索和學習!

Credits: Image by storyset