Python
Halaman SebelumnyaHalaman Berikutnya
Kode apa pun yang Anda tulis menggunakan bahasa yang dikompilasi seperti C, C++, atau Java dapat diintegrasikan atau diimpor ke skrip Python lain. Kode ini dianggap sebagai "ekstensi".
Modul ekstensi Python tidak lebih dari pustaka C normal. Pada mesin Unix, library ini biasanya diakhiri dengan .so (untuk objek bersama). Pada mesin Windows, Anda biasanya melihat .dll (untuk perpustakaan yang ditautkan secara dinamis).
Untuk mulai menulis ekstensi, Anda memerlukan file header Python.
Pada mesin Unix, ini biasanya memerlukan penginstalan paket khusus pengembang seperti python2.5-dev.
Pengguna Windows mendapatkan header ini sebagai bagian dari paket saat mereka menggunakan penginstal Python biner.
Selain itu, diasumsikan bahwa Anda memiliki pengetahuan yang baik tentang C atau C++ untuk menulis Ekstensi Python apa pun menggunakan pemrograman C.
Untuk tampilan pertama Anda pada modul ekstensi Python, Anda perlu mengelompokkan kode Anda menjadi empat bagian −
File header Python.h .
Fungsi C yang ingin Anda tampilkan sebagai antarmuka dari modul Anda.
Tabel yang memetakan nama fungsi Anda saat pengembang Python melihatnya ke fungsi C di dalam modul ekstensi.
Fungsi inisialisasi.
Anda perlu menyertakan Python.h header di file sumber C Anda, yang memberi Anda akses ke API Python internal yang digunakan untuk menghubungkan modul Anda ke penerjemah.
Pastikan untuk menyertakan Python.h sebelum header lain yang mungkin Anda perlukan. Anda harus mengikuti penyertaan dengan fungsi yang ingin Anda panggil dari Python.
Tanda tangan implementasi C dari fungsi Anda selalu mengambil salah satu dari tiga bentuk berikut −
static PyObject *MyFunction( PyObject *self, PyObject *args );static PyObject *MyFunctionWithKeywords(PyObject *self, PyObject *args, PyObject *kw);static PyObject *gs(self PyObject)WithNobject;
Masing-masing dari deklarasi sebelumnya mengembalikan objek Python. Tidak ada yang namanya kekosongan function di Python seperti yang ada di C. Jika Anda tidak ingin fungsi Anda mengembalikan nilai, kembalikan C setara dengan None Python nilai. Header Python mendefinisikan makro, Py_RETURN_NONE, yang melakukan ini untuk kita.
Nama fungsi C Anda bisa apa saja yang Anda suka karena tidak pernah terlihat di luar modul ekstensi. Mereka didefinisikan sebagai statis fungsi.
Fungsi C Anda biasanya diberi nama dengan menggabungkan modul Python dan nama fungsi bersama-sama, seperti yang ditunjukkan di sini −
PyObject statis *module_func (PyObject *self, PyObject *args) { /* Lakukan pekerjaan Anda di sini. */ Py_RETURN_NONE;}
Ini adalah fungsi Python yang disebut fungsi di dalam modul modul . Anda akan meletakkan pointer ke fungsi C Anda ke dalam tabel metode untuk modul yang biasanya muncul berikutnya dalam kode sumber Anda.
Tabel metode ini adalah array sederhana dari struktur PyMethodDef. Struktur itu terlihat seperti ini
struct PyMethodDef { char *ml_name; PyCFunction ml_meth; int ml_flags; char *ml_doc;};
Berikut adalah deskripsi anggota struktur ini
ml_name Ini adalah nama fungsi yang disajikan oleh juru bahasa Python ketika digunakan dalam program Python.
ml_meth Ini harus alamat ke fungsi yang memiliki salah satu tanda tangan yang dijelaskan di bagian sebelumnya.
ml_flags Ini memberi tahu penerjemah mana dari tiga tanda tangan yang digunakan ml_meth.
Bendera ini biasanya memiliki nilai METH_VAARGS.
Bendera ini dapat bitwise ATAU dengan METH_KEYWORDS jika Anda ingin mengizinkan argumen kata kunci ke dalam fungsi Anda.
Ini juga dapat memiliki nilai METH_NOARGS yang menunjukkan bahwa Anda tidak ingin menerima argumen apa pun.
ml_doc Ini adalah docstring untuk fungsi tersebut, yang dapat berupa NULL jika Anda tidak ingin menulisnya.
Tabel ini perlu diakhiri dengan sentinel yang terdiri dari nilai NULL dan 0 untuk anggota yang sesuai.
Untuk fungsi yang didefinisikan di atas, kami memiliki tabel pemetaan metode berikut
modul PyMethodDef statis _metode[] ={ { "fungsi ", (PyCFunction)module_func , METH_NOARGS, NULL }, { NULL, NULL, 0, NULL }};
Bagian terakhir dari modul ekstensi Anda adalah fungsi inisialisasi. Fungsi ini dipanggil oleh interpreter Python ketika modul dimuat. Fungsi tersebut harus diberi nama initModul , di mana Modul adalah nama modul.
Fungsi inisialisasi perlu diekspor dari perpustakaan yang akan Anda bangun. Header Python mendefinisikan PyMODINIT_FUNC untuk menyertakan mantra yang sesuai agar hal itu terjadi untuk lingkungan tertentu tempat kami mengompilasi. Yang harus Anda lakukan adalah menggunakannya saat mendefinisikan fungsi.
Fungsi inisialisasi C Anda umumnya memiliki struktur keseluruhan berikut
PyMODINIT_FUNC initModul () { Py_InitModule3(fungsi , modul _methods, "docstring...");}
Berikut adalah deskripsi Py_InitModule3 fungsi
menyenangkan Ini adalah fungsi yang akan diekspor.
modul _metode Ini adalah nama tabel pemetaan yang didefinisikan di atas.
doktrin Ini adalah komentar yang ingin Anda berikan di ekstensi Anda.
Menyatukan ini semua terlihat seperti berikut −
#includePyObject statis *module_func (PyObject *self, PyObject *args) { /* Lakukan pekerjaan Anda di sini. */ Py_RETURN_NONE;}modul PyMethodDef statis _metode[] ={ { "fungsi ", (PyCFunction)module_func , METH_NOARGS, NULL }, { NULL, NULL, 0, NULL }};PyMODINIT_FUNC initModul () { Py_InitModule3(fungsi , modul _methods, "docstring...");}
Contoh sederhana yang menggunakan semua konsep di atas
#includestatic PyObject* helloworld(PyObject* self) { return Py_BuildValue("s", "Halo, ekstensi Python!!");}static char helloworld_docs[] ="helloworld( ):Pesan apa pun yang ingin Anda taruh di sini!!\n";static PyMethodDef helloworld_funcs[] ={ {"helloworld", (PyCFunction)helloworld, METH_NOARGS, helloworld_docs}, {NULL}};void inithelloworld(void) { Py_InitModule3("helloworld", helloworld_funcs, "Contoh modul ekstensi!");}
Ini Py_BuildValue fungsi digunakan untuk membangun nilai Python. Simpan kode di atas dalam file hello.c. Kita akan melihat bagaimana mengkompilasi dan menginstal modul ini untuk dipanggil dari skrip Python.
Distutil package membuatnya sangat mudah untuk mendistribusikan modul Python, baik Python murni maupun modul ekstensi, dengan cara standar. Modul didistribusikan dalam bentuk sumber dan dibuat serta diinstal melalui skrip penyiapan yang biasanya disebut setup.py sebagai berikut.
Untuk modul di atas, Anda perlu menyiapkan skrip setup.py berikut
dari distutils.core import setup, Extensionsetup(name='helloworld', version='1.0', \ ext_modules=[Extension('helloworld', ['hello.c'])])
Sekarang, gunakan perintah berikut, yang akan melakukan semua langkah kompilasi dan penautan yang diperlukan, dengan perintah dan flag compiler dan linker yang tepat, dan menyalin pustaka dinamis yang dihasilkan ke direktori yang sesuai −
$ python setup.py install
Pada sistem berbasis Unix, kemungkinan besar Anda harus menjalankan perintah ini sebagai root agar memiliki izin untuk menulis ke direktori paket situs. Ini biasanya bukan masalah di Windows.
Setelah Anda menginstal ekstensi Anda, Anda akan dapat mengimpor dan memanggil ekstensi itu dalam skrip Python Anda sebagai berikut −
#!/usr/bin/pythonimport helloworldprint helloworld.helloworld()
Ini akan menghasilkan hasil berikut
Halo, ekstensi Python!!
Karena kemungkinan besar Anda ingin mendefinisikan fungsi yang menerima argumen, Anda dapat menggunakan salah satu tanda tangan lain untuk fungsi C Anda. Misalnya, fungsi berikut, yang menerima sejumlah parameter, akan didefinisikan seperti ini
PyObject statis *module_func (PyObject *self, PyObject *args) { /* Parsing args dan lakukan sesuatu yang menarik di sini. */ Py_RETURN_NONE;}
Tabel metode yang berisi entri untuk fungsi baru akan terlihat seperti ini
modul PyMethodDef statis _metode[] ={ { "fungsi ", (PyCFunction)module_func , METH_NOARGS, NULL }, { "fungsi ", modul_fungsi , METH_VARARGS, NULL }, { NULL, NULL, 0, NULL }};
Anda dapat menggunakan API PyArg_ParseTuple fungsi untuk mengekstrak argumen dari satu pointer PyObject yang diteruskan ke fungsi C Anda.
Argumen pertama untuk PyArg_ParseTuple adalah argumen args. Ini adalah objek yang akan Anda parsing . Argumen kedua adalah string format yang menjelaskan argumen seperti yang Anda harapkan muncul. Setiap argumen diwakili oleh satu atau lebih karakter dalam format string sebagai berikut.
PyObject statis *module_func (PyObject *self, PyObject *args) { int i; ganda d; karakter *s; if (!PyArg_ParseTuple(args, "id", &i, &d, &s)) { kembali NULL; } /* Lakukan sesuatu yang menarik di sini. */ Py_RETURN_NONE;}
Mengkompilasi versi baru modul Anda dan mengimpornya memungkinkan Anda untuk memanggil fungsi baru dengan sejumlah argumen jenis apa pun −
module.func(1, s="three", d=2.0)module.func(i=1, d=2.0, s="three")module.func(s=" tiga", d=2.0, i=1)
Anda mungkin bisa membuat lebih banyak variasi.
Berikut adalah tanda tangan standar untuk PyArg_ParseTuple fungsi
int PyArg_ParseTuple(PyObject* tuple,char* format,...)
Fungsi ini mengembalikan 0 untuk kesalahan, dan nilai yang tidak sama dengan 0 untuk keberhasilan. tuple adalah PyObject* yang merupakan argumen kedua fungsi C. Berikut format adalah string C yang menjelaskan argumen wajib dan opsional.
Berikut adalah daftar kode format untuk PyArg_ParseTuple fungsi
Kode | Tipe C | Arti |
---|---|---|
c | char | String Python dengan panjang 1 menjadi karakter C. |
d | ganda | Float Python menjadi double C. |
f | mengambang | Apungan Python menjadi pelampung C. |
i | int | Int Python menjadi int C. |
l | panjang | Int Python menjadi panjang C. |
L | panjang panjang | Int Python menjadi panjang C |
O | PyObject* | Mendapatkan referensi pinjaman non-NULL untuk argumen Python. |
s | char* | String python tanpa null yang disematkan ke C char*. |
s# | char*+int | Semua string Python ke alamat dan panjang C. |
t# | char*+int | Buffer segmen tunggal read-only ke alamat dan panjang C. |
u | Py_UNICODE* | Python Unicode tanpa menyematkan null ke C. |
u# | Py_UNICODE*+int | Alamat dan panjang Python Unicode C apa saja. |
w# | char*+int | Baca/tulis buffer segmen tunggal ke alamat dan panjang C. |
z | char* | Seperti s, juga menerima None (menyetel C char* ke NULL). |
z# | char*+int | Seperti s#, juga menerima None (menyetel C char* ke NULL). |
(...) | sesuai ... | Urutan Python diperlakukan sebagai satu argumen per item. |
Argumen berikut ini opsional. | ||
Format akhir, diikuti dengan nama fungsi untuk pesan kesalahan. | ||
Format akhir, diikuti oleh seluruh teks pesan kesalahan. |
Py_BuildValue mengambil format string seperti PyArg_ParseTuple melakukan. Alih-alih meneruskan alamat nilai yang Anda buat, Anda meneruskan nilai sebenarnya. Berikut adalah contoh yang menunjukkan cara menerapkan fungsi tambah −
static PyObject *foo_add(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { kembali NULL; } mengembalikan Py_BuildValue("i", a + b);}
Beginilah jadinya jika diimplementasikan dengan Python
def add(a, b):return (a + b)
Anda dapat mengembalikan dua nilai dari fungsi Anda sebagai berikut, ini akan ditangkap menggunakan daftar dengan Python.
static PyObject *foo_add_subtract(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { kembali NULL; } mengembalikan Py_BuildValue("ii", a + b, a - b);}
Beginilah jadinya jika diimplementasikan dengan Python
def add_subtract(a, b):return (a + b, a - b)
Berikut adalah tanda tangan standar untuk Py_BuildValue fungsi
PyObject* Py_BuildValue(char* format,...)
Berikut format adalah string C yang menjelaskan objek Python yang akan dibangun. Argumen berikut dari Py_BuildValue adalah nilai C dari mana hasilnya dibangun. PyObject* hasilnya adalah referensi baru.
Tabel berikut mencantumkan string kode yang umum digunakan, di mana nol atau lebih digabungkan ke dalam format string.
Kode | Tipe C | Arti |
---|---|---|
c | char | A C char menjadi string Python dengan panjang 1. |
d | ganda | A C double menjadi float Python. |
f | mengambang | Apungan C menjadi pelampung Python. |
i | int | Int C menjadi int Python. |
l | panjang | Panjang C menjadi int Python. |
T | PyObject* | Meneruskan objek Python dan mencuri referensi. |
O | PyObject* | Meneruskan objek Python dan memasukkannya seperti biasa. |
O& | convert+void* | Konversi sewenang-wenang |
s | char* | C 0-dihentikan char* ke string Python, atau NULL ke None. |
s# | char*+int | C char* dan panjangnya ke string Python, atau NULL ke None. |
u | Py_UNICODE* | C-wide, string diakhiri null ke Python Unicode, atau NULL ke None. |
u# | Py_UNICODE*+int | String lebar-C dan panjang ke Python Unicode, atau NULL ke None. |
w# | char*+int | Baca/tulis buffer segmen tunggal ke alamat dan panjang C. |
z | char* | Seperti s, juga menerima None (menyetel C char* ke NULL). |
z# | char*+int | Seperti s#, juga menerima None (menyetel C char* ke NULL). |
(...) | sesuai ... | Membangun tupel Python dari nilai C. |
[...] | sesuai ... | Membuat daftar Python dari nilai C. |
{...} | sesuai ... | Membangun kamus Python dari nilai C, kunci dan nilai bergantian. |
Kode {...} membangun kamus dari jumlah nilai C yang genap, secara bergantian kunci dan nilai. Misalnya, Py_BuildValue("{issi}",23,"zig","zag",42) mengembalikan kamus seperti {23:'zig','zag':42} Python.
Python
1. Bagaimana kita bisa sampai di sini? Hari lain, serangkaian pengungkapan keamanan yang mengecewakan. Peretas Rusia mencuri 1,2 miliar kata sandi (http://blogs.wsj.com/digits/2014/08/05/security-firm-russian-hackers-amassed-1-2-billion-web-credentials/), dan Airplanes Can Diretas melalui Sistem Wi
Artikel ini tentang Geo IoT mencakup kemungkinan besar untuk melacak dan menemukan perangkat. Johanna Konrad-Mausser menyebutkan tujuh faktor penting untuk membuat proyek Geo IoT Anda sukses. Mengetahui lokasi yang tepat dari aset Anda – apakah itu mesin X-ray portabel atau de-icer pesawat – meng
Saat meneliti beberapa jenis baut yang berbeda, Anda mungkin menemukan baut elevator. Seperti semua baut, mereka memiliki kepala dan betis berulir. Baut lift, bagaimanapun, dirancang secara berbeda. Mereka memiliki beberapa fitur halus yang membedakannya dari baut standar. Apa sebenarnya baut elevat
Steve Multer duduk bersama Brian Ray, CEO Link Labs, di Internet of Things World Forum di Chicago untuk membicarakan masa depan jaringan berdaya rendah dan luas, dan bagaimana jaringan ini dapat memecahkan masalah yang sulit.
MQ rangkaian sensor gas menggunakan pemanas kecil di dalam dengan sensor elektrokimia sensor ini sensitif terhadap berbagai gas yang digunakan pada suhu kamar. Sensor alkohol MQ135 adalah Sno2 dengan konduktivitas udara bersih yang lebih rendah. Ketika gas ledakan target ada, maka konduktivitas sens
Kecerdasan buatan secara luas diakui sebagai aspek penting dari apa yang secara luas disebut sebagai Industri 4.0. Meskipun belum ada yang tahu bagaimana kecerdasan buatan akan dimasukkan ke dalam fase berikutnya dari Revolusi Industri, sebagian besar setuju bahwa itu akan memungkinkan konektivitas