Probleme bei der Verwendung von C-Code in Python | Set 2
Voraussetzung: Probleme bei der Verwendung von C-Code in Python | Set 1
Die DoubleArrayType- Klasse kann die Situation von Python mit verschiedenen Formen wie Array, Numpy-Array, Liste und Tupel behandeln. In dieser Klasse wird eine einzelne Methode from_param()
definiert. Diese Methode verwendet einen einzelnen Parameter und beschränkt ihn auf ein kompatibles ctypes-Objekt ( ctypes.c_double
im Beispiel einen Zeiger auf a ).
Im folgenden Code wird der Typname des Parameters extrahiert und zum Versenden an eine speziellere Methode verwendet. Wenn beispielsweise eine Liste übergeben wird, lautet der Typname list und eine Methode from_list()
wird aufgerufen. Für Listen und Tupel führt die from_list()
Methode eine Konvertierung in ein ctypes-Array-Objekt durch.
Code # 1:
nums
=
[
1
,
2
,
3
]
a
=
(ctypes.c_double
*
len
(nums))(
*
nums)
(
"a : "
, a)
(
"\na[0] : "
, a[
0
])
(
"\na[1] : "
, a[
1
])
(
"\na[2] : "
, a[
2
])
Ausgabe :
a: <__ main __. c_double_Array_3-Objekt bei 0x10069cd40> a [0]: 1,0 a [1]: 2,0 a [2]: 3,0
Die Methode extrahiert den zugrunde liegenden Speicherzeiger und wandelt ihn in ein ctypes-Zeigerobjekt für Array-Objekte um. from_array()
Code # 2:
import
array
arr
=
array.array(
'd'
, [
1
,
2
,
3
])
(
"arr : "
, arr)
ptr_
=
a.buffer_info()
(
"\nptr :"
, ptr)
(
"\n"
, ctypes.cast(ptr, ctypes.POINTER(ctypes.c_double)))
Ausgabe :
arr: array ('d', [1.0, 2.0, 3.0]) ptr: 4298687200 <__ main __. LP_c_double-Objekt bei 0x10069cd40>
Das from_ndarray()
zeigt einen vergleichbaren Konvertierungscode für Numpy-Arrays. Durch Definieren der DoubleArrayType- Klasse und deren Verwendung in der Typensignatur von avg()
kann die Funktion eine Vielzahl verschiedener Array-ähnlicher Eingaben akzeptieren.
Code # 3:
import
sample
import
array
import
numpy
(
"Average of list : "
, sample.avg([
1
,
2
,
3
]))
(
"\nAverage of tuple : "
, sample.avg((
1
,
2
,
3
)))
(\nAverage of array : ", sample.avg(array.array(
'd'
, [
1
,
2
,
3
])))
(\nAverage of numpy array : ", sample.avg(numpy.array([
1.0
,
2.0
,
3.0
])))
Ausgabe :
Durchschnitt der Liste: 2.0 Durchschnitt des Tupels: 2,0 Durchschnitt des Arrays: 2.0 Durchschnitt des Numpy-Arrays: 2,0
Um mit einer einfachen C-Struktur zu arbeiten, definieren Sie einfach eine Klasse, die die entsprechenden Felder und Typen enthält, wie im folgenden Code gezeigt. Nach dem Definieren kann die Klasse in Typensignaturen sowie in Code verwendet werden, der instanziiert werden und mit den Strukturen arbeiten muss.
Code # 4:
class
Point(ctypes.Structure):
_fields_
=
[(
'x'
, ctypes.c_double),
(
'y'
, ctypes.c_double)]
point1
=
sample.Point(
1
,
2
)
point2
=
sample.Point(
4
,
5
)
(
"pt1 x : "
, point1.x)
(
"\npt1 y : "
, point1.y)
(
"\nDistance between pt1 and pt2 : "
,
sample.distance(point1, point2))
Ausgabe :
pt1 x: 1,0 pt1 y: 2,0 Abstand zwischen pt1 und pt2: 4.242640687119285