Przekazywanie argumentów do tp_new i tp_init z podtypów w Python C API

Pierwotnie zadałem to pytanie na liście capi-sig Pythona:Jak przekazać argumenty do tp_new i tp_init z podtypów?

Czytam PythonaPEP-253 na temat podtypów i istnieje wiele dobrych zaleceń na temat struktury typów, zadzwońtp_new itp_init automaty itp.

Brakuje jednak ważnej notatki dotyczącej przekazywania argumentów z sub do super typu. Wydaje sięPEP-253 jest niedokończone zgodnie z uwagą:

(XXX Powinien być akapit lub dwa o przekazywaniu argumentów tutaj.)

Próbuję więc ekstrapolować niektóre strategiedobrze znany z podtypowania klas Pythona, zwłaszcza techniki, w których każdy poziom usuwa argumenty itp.

Szukam technik, aby osiągnąć podobny efekt, ale używając zwykłegoPython C API (3.x):

class Shape:
    def __init__(self, shapename, **kwds):
        self.shapename = shapename
        super().__init__(**kwds)

class ColoredShape(Shape):
    def __init__(self, color, **kwds):
        self.color = color
        super().__init__(**kwds)

Jaki byłby odpowiednik w Python C API?

Jak radzić sobie z podobną sytuacją, ale z oczekiwanymi argumentami specyficznymi dla klasy pochodnej w innej kolejności? Jest to argumenty podane na końcu krotki argumentów (lubkwds Dict, zakładam, że zasada będzie taka sama.

Oto kod (pseudo) ilustrujący sytuację:

class Base:
   def __init__(self, x, y, z):
      self.x = x
      self.y = y
      self.z = z

class Derived(Base):
   def __init__(self, x, y, a):
      self.a = a
      super().__init__(x, y, None):

Uwaga, jeślia oczekiwano najpierw:

Derived.__init__(self, a, x, y)

byłaby podobna sytuacja doShape iColoredShape powyżej. Zakładam, że łatwiej byłoby sobie z tym poradzić.

Czy ktoś mógłby pomóc w odnalezieniu zaginionegoXXX wspomniany powyżej komentarz i poprawna technika przekazywania argumentów z podtypu do super typu (ów) w konstrukcji?

AKTUALIZACJA 2012-07-17:

Zainspirowany przezodpowiedź ecatmur poniżej przejrzałem źródła Pythona 3 i znalazłemdefdict_init konstruktorcollections.defaultdict obiekt typu interesujący. Typ pochodzi odPyDictObject a jego konstruktor przyjmuje dodatkowy argumentdefault_factory. Podpis konstruktora w klasie Pythona jest następujący:

class collections.defaultdict([default_factory[, ...]])

Oto jakdefault_factory jest pozbawiony oryginałuargs krotka, więc pozostałe argumenty są przekazywane dotp_init typu podstawowegoPyDictObject:

int result;
PyObject *newargs;
Py_ssize_t n = PyTuple_GET_SIZE(args);
...
newargs = PySequence_GetSlice(args, 1, n);
...
result = PyDict_Type.tp_init(self, newargs, kwds);

Uwaga: ta wycięta obecność dotyczy tylko odpowiedniej częścidefdict_init funkcjonować.

questionAnswers(3)

yourAnswerToTheQuestion