2017-01-28 17 views
7

Pracuję nad dokumentacją rozszerzenia Python C dla definiowania nowych typów i właśnie skończyłem rozdział Providing finer control over data attributes.Czy jest jakaś korzyść z używania Py_DECREF zamiast Py_XDECREF dla rozszerzeń Python C?

W tej sekcji one zmienić kod przykładowy, aby zapewnić, że first i last atrybuty Noddy struktury nie może być NULL, na przykład poprzez inicjowanie atrybutów do pustych strun w new i dodanie pobierające i ustawiające, które podnoszą TypeError if użytkownik próbuje usunąć lub w inny sposób ustawić te atrybuty na wartość Null.

Dodatkowo (a punktem moje pytanie), autor zmienia cały Py_XDECREF do Py_DECREF dla tych atrybutów, stwierdzając, że:

z tymi zmianami, możemy zapewnić, że pierwszy i ostatni członkowie są nigdy NULL, abyśmy mogli usunąć sprawdzenia wartości NULL w prawie wszystkich przypadkach. Oznacza to, że większość wywołań Py_XDECREF() można przekonwertować na wywołania Py_DECREF(). Jedynym miejscem, w którym nie możemy zmienić tych wywołań, jest deallocator, gdzie istnieje możliwość, że inicjacja tych elementów nie powiodła się w konstruktorze.

Wydaje mi się, że byłoby to po prostu bezpieczniejsze w użyciu Py_XDECREF, zważywszy, że Py_DECREF skutkuje segmentation fault jeśli jego wartość przeszedł NULL.

Jaka jest korzyść z używania Py_DECREF przez Py_XDECREF?

Odpowiedz

5

Jeśli wiesz, że obiekt nie może być NULL, korzyści z Py_DECREF ponad Py_XDECREF są następujące:

  • jest szybszy, ponieważ pozwala uniknąć niepotrzebnych testów i skoku;
  • dodatkowo zapewnia to, co jest faktycznie twierdzeniem o zerowym koszcie, że wskaźnik jest nie-NULL - program natychmiast ulegnie awarii, jeśli niezmiennik zostanie zerwany.

Oba punkty mogą być ważne, gdy do czynienia z kodem niskim poziomie, dlatego rdzeń Python i większość rozszerzenia są uważać, aby używać tylko Py_XDECREF (lub Py_CLEAR), gdy wskaźnik w rzeczywistości może być NULL.