Python | Непрозрачные указатели в модулях расширения C
Давайте обсудим модуль расширения, который должен обрабатывать указатель на структуру данных C, не раскрывая какие-либо внутренние детали структуры Python. Непрозрачные структуры данных можно легко обработать, заключив их в объекты капсулы, как показано в фрагменте кода ниже.
Code #1 :
typedef struct Point { double x, y; } Point; extern double distance(Point *p1, Point *p2); |
Обратитесь к предыдущей статье, чтобы найти функцию distance () - Использование кодов C в Python.
Code #2 : Code given is an extension code that wraps the Point structure and distance()
function using capsules.
/* Destructor function for points */ static void del_Point(PyObject * obj) { free (PyCapsule_GetPointer(obj, "Point" )); } /* Utility functions */ static Point * PyPoint_AsPoint(PyObject * obj) { return (Point *) PyCapsule_GetPointer(obj, "Point" ); } static PyObject * PyPoint_FromPoint(Point * p, int must_free) { return PyCapsule_New(p, "Point" , must_free ? del_Point : NULL); } /* Create a new Point object */ static PyObject * py_Point(PyObject * self, PyObject * args) { Point * p; double x, y; if (! PyArg_ParseTuple(args, "dd" , &x, &y)) { return NULL; } p = (Point *) malloc ( sizeof (Point)); p->x = x; p->y = y; return PyPoint_FromPoint(p, 1); } static PyObject * py_distance(PyObject * self, PyObject * args) { Point * p1, *p2; PyObject * py_p1, *py_p2; double result; if (! PyArg_ParseTuple(args, "OO" , &py_p1, &py_p2)) { return NULL; } if (!(p1 = PyPoint_AsPoint(py_p1))) { return NULL; } if (!(p2 = PyPoint_AsPoint(py_p2))) { return NULL; } result = distance(p1, p2); return Py_BuildValue( "d" , result); } |
Код # 3: Использование указанной выше функции в Python
import sample pt1 = sample.Point( 2 , 3 ) pt2 = sample.Point( 4 , 5 ) print ( "pt1 : " , pt1) print ( "
pt2 : " , pt2) print ( "Distance : " , sample.distance(p1, p2)) |
Выход :
pt1: <объект-капсула "Point" по адресу 0x1004ea330> pt2: <объект-капсула "Point" по адресу 0x1005d1db0> Расстояние: 2.8284271247461903
- Capsules are similar to a typed C pointer.
- They hold a generic pointer along with an identifying name and can be easily created using the
PyCapsule_New()
function. PyCapsule_GetPointer()
function is used to extract the pointer contained inside a capsule.- Garbage collection and memory management is a tricky part that concerns about the capsules.
PyPoint_FromPoint()
function accepts a must_free argument that indicates whether the underlying Point * structure is to be collected when the capsule is destroyed.
Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.
Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.