[C-API] tp_getattro - Funktionen werden nicht aufgerufen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hallo,
mein nächstes Problem bezieht sich auch tp_getattro. Sobald ich dieses Feld definiere, werden alle Funktionsaufrufe dahin "umgeleitet". Das heißt, dass selbst Methoden, die ich in tp_methods definiere, nicht aufgerufen werden. Stattdessen wird der Funktionsname an tp_getattro übergeben?!

Wo ist denn da bitte der Sinn?

Gruß
Grüßle.
BlackJack

@Chrisber: Dann definiere das Feld halt nicht. Der Sinn ist der selbe wie `__getattribute__` in Python. Kann man zum Beispiel verwenden um Proxy-Objekte zu schreiben, die etwas mit dem Aufruf und den Daten anstellen und/oder es einfach an ein anderes Objekt durch reichen.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Ich wollte eigentlich das selbe Verhalten herbeiführen wie bei __getattr__ in einer Klasse. Und wenn es eine Funktion gibt, wird diese aufgerufen, und nicht __getattr__...

Gruß
Grüßle.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Der korrekte Weg, ein __getattr__-Äquivalent zu bekommen, ist es, `tp_getattr` zu überschreiben und darin für alle Attribute, die nicht "speziell" sind, das `tp_getattr` der Superklasse aufzurufen (in den meisten Fällen `PyObject_GenericGetAttr` wenn ich das richtig in Erinnerung habe).

Falls es in deinem Anwendungsfall keine "Positivliste" gibt, sondern das Ganze nur als Fallback gelten soll, kannst du ja auch sowas in der Art machen:

Code: Alles auswählen

static PyObject* blah_getattr(PyObject* obj, const char* attr)
{
  PyObject* result;
  result = PyObject_GenericGetAttr(obj, attr);
  if(result == NULL) {
    /* __getattr__ magic here */
  }
  return result;
}
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Ich habe mir eben genau wegen folgendem Satz von hier:
This field is deprecated.
gedacht, dass man besser tp_getattro benutzen sollte. Manchmal ist die Doku schon seeeeehr schwer verständlich, wie ich finde (Schul-Englisch 12. Klasse, ...).

Gruß und Danke, mit tp_getattr geht es.
Grüßle.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

`tp_getattr` sollte sich doch genau so verhalten wie `tp_getattro`, nur dass zweiteres einen Python-String und ersteres ein Null-terminiertes Char-Array erwartet, oder hab ich da was falsch verstanden?

Der Punkt meines vorigen Beitrages war folglich nicht, dass man `tp_getattr` statt `tp_getattro` nutzen sollte, sondern, dass man, wenn man `__getattr__` imitieren will, eines von beiden durch eine Routine, die die entsprechende Super-Methode aufruft, überschreiben soll.
Antworten