[C] Fragen zu Methodenparametern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Habe mal eine Frage zu Methodenparametern in C-Python Methoden.

1. Verschiedene Parameter
Ich möchte, dass man die Funktion so und so aufrufen kann:
Func(int)
Func(int, bool)
Dann müsste der Code doch so aussehen, richtig?:

Code: Alles auswählen

	int iUserID;
	bool bMute = true;

	if (PyArg_ParseTuple(args, "i|ib", &iUserID, &bMute))
		blablub();
2. Übergabe von Listen
Ich brauche außerdem noch eine Funktion, bei dem ich eine Liste unbestimmer Länge übergeben kann. Laut PyDoc finde ich da aber nichts drüber, nur über Listen mit bestimmten Längen und Typen:

Code: Alles auswählen

int i1, i2;

if (PyArg_ParseTuple(args, "[ii]", &i1, &i2))
		blablub();
Gibt es auch eine Möglichkeit, alle Einträge der Liste in ein Array oder sonst was zu packen?

~ Chris[/b]
Grüßle.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

ad 1: Nein. Das "|" zeigt an, das die folgenden Argumente optional sind. "i|ib" ist also zu interpretieren als "ein Integer und u. U. noch ein Integer und ein tiny int. Bools gibt es in C nicht, das wäre also eine ein Pythonobjekt. Demnach kontrollierst Du auf "i|O" oder "i|O&", falls Du das O& über einen Konverter gehen lässt, der z. B. 1 oder 0 in die Variable schreibt, was dem gewünschten Resultat vielleicht nahe kommt.

ad 2: Ebenfalls so eher nicht. Wie wäre:

Code: Alles auswählen

data_type *my_object = NULL;
int *py_list = NULL;
int size;
if (!PyArg_ParseTuple(args, "O", &py_list))
    return NULL;
size = PyList_Size(py_list);
my_object = malloc(sizeof(data_type) * size);
/* transfer in die interne Darstellung */
for (i = 0; i < size; i++) {
  /* diverse Operationen z. B. mit PyList_GetItem und
     ähnlichen Dingen - hängt von Deinen Wünschen ab */
}
HTH
Christian

PS Bin nicht mehr firm in diesen Dingen, da ich vor einiger Zeit auf SWIG gewechselt habe. Vielleicht ist das was für Dich? ;-)
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Danke für deine Antworten, die haben mir sehr geholfen :)

Zu 1: Naja doch, das "b" funktioniert wunderbar. Vielleicht wird's von Python automatisch konvertiert, jedenfalls stimmt der wert im bool ;)

Zu 2: Genau das habe ich gesucht. Danke!!!

~ Chris
Grüßle.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ups, es muß natürlich heissen:

Code: Alles auswählen

PyObject *py_list = NULL;
Und was die implizite Umwandlung anbelangt: Kann schon sein, habe ich nocht nicht ausprobiert. Ich möchte raten, dass dies an der internen Implementierung des Datentyps liegt - aber ob das in allen Fällen funktioniert ist nicht garantiert. Besser ist wohl auf den entsprechenden Teil der API zurückzufallen.

Gruß,
Christian
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Jo, dass das ein PyObject sein musste, war ja logisch :)
Ok, wenn das so einfach ist, werde ich dann wohl doch die interne Umwandlung benutzen.

Danke :)

~ Chris
Grüßle.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Ich hab damit jetzt rumgespielt.
Python erkennt die richtig Größe der Liste :)
Hier ist mal mein Code:

Code: Alles auswählen

	for (int i = 0; i < PyList_Size(pyList); i++)
	{
		int iUserID = -1;
		PyArg_ParseTuple(PyList_GetItem(pyList, i), "i", &iUserID);
		Msg("%i\n", iUserID);
	}
Das ganze funktioniert zwar, aber PyArg_ParseTuple will nicht. In der Console steht folgender Error:

Code: Alles auswählen

SystemError: new style getargs format but argument is not a tuple
Der Fehler ist mir zwar klar, aber wie soll ich sonst den Eintrag aus der Liste parsen/bekommen?

Sorry für den Doppelpost, aber sonst guckt wahrscheinlich keiner mehr ins Thema.

EDIT: Habs. Einfach PyArg_Parse, ich depp.

~ Chris
Grüßle.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hm, PyArg_Parse ist zu meinem Erstaunen sogar noch in der API zu 3.0 enthalten, aber nicht direkt empfehlenswert.

PyList_GetItem mit PyInt_AsLong ist vielleicht das Beste, wenn Du mit ganzzahligen Werten arbeiten willst.
@Alle: Sehe ich das richtig?

Das wäre dann:

Code: Alles auswählen

PyObject * dummy_1 = NULL;
for (i = 0; i < size; i++) {
  dummy_1 = PyList_GetItem(py_list, i);
  my_long = PyInt_AsLong(dummy_1);
  ...
}
Wobei man auf dummy_1 verzichten kann - ich habe es nur der Übersichtlichkeit eingeführt.

Vorsicht: Ich bin mir gerade nicht sicher, ob ich die Referenzen richtig behandelt habe - bin schon müde.

Gruß,
Christian
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

CM hat geschrieben: PyList_GetItem mit PyInt_AsLong ist vielleicht das Beste, wenn Du mit ganzzahligen Werten arbeiten willst.
@Alle: Sehe ich das richtig?
Ja.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten