Przedrostek podkreślenia w dużej mierze oznacza to samo w C API, co w normalnym Pythonie: "ta funkcja jest przedmiotem implementacji podlegającym zmianie, więc uważaj, jeśli jej używasz". Nie ma zakazu korzystania z takich funkcji i jeśli jest to jedyny sposób na osiągnięcie określonego celu (np. Znaczący przyrost wydajności w twoim przypadku), możesz używać interfejsu API, dopóki jesteś świadomy zagrożenia.
Jeśli interfejs API _PyLong_FromByteArray
był rzeczywiście prywatny, byłaby to funkcja static
i nie zostałaby w pełni udokumentowana i wyeksportowana w postaci longobject.h
. W rzeczywistości, Tim Peters (znany Python rdzeń deweloper) wyraźnie blesses its use:
[Dan Christensen]
Mój uczeń i ja pisząc rozszerzenie C, który produkuje dużą całkowitą w formacie binarnym które chcemy przekonwertować na długi python. Liczba bitów może być większa niż 32 lub nawet 64. Mój uczeń znalazł funkcję _PyLong_FromByteArray w longobject.h, która jest dokładnie , czego potrzebujemy, ale wiodący podkreślenie sprawia, że jestem ostrożny. Czy korzystanie z tej funkcji jest bezpieczne dla ?
Python używa go wewnętrznie, więc lepiej być ;-)
będzie nadal istnieć w przyszłych wersjach Pythona?
Brak gwarancji, a to dlatego, że ma wiodącą podkreślenia: to nie oficjalnie obsługiwane, zewnętrznie udokumentowane, część reklamowanych Python/C API. Tak się składa, że dodałem tę funkcję, ponieważ Python potrzebował jakiejś formy wewnętrznej funkcji w różnych modułach C w postaci .Uczynienie go oficjalną częścią Python/C API byłoby znacznie więcej pracy (na którą nie miałem czasu), a stworzył wieczne nowe obciążenie konserwacyjne (które nie jestem zainteresowany niezależnie;)).
W praktyce niewielu ludzi dotknie tej części implementacji Pythona, więc Nie oczekuję, że zniknie, a nawet zmieni się, na lata. Największą niepewnością, jaką mogę sobie wyobrazić, jest to, że ktoś może rozpocząć krucjatę, aby utworzyć inny bajtowy szereg < -> długi interfejs "oficjalny" oparty na innym sposobie reprezentowania ujemnych liczb całkowitych. Ale nawet wtedy spodziewam obecne funkcje nieoficjalne pozostać, ponieważ reprezentacja 256's-dopełnienie pozostaje niezbędna dla formatu „Q” w struct
modułu, a dla protokołu modułu pickle
= 2 długo formatu serializacji.
Czy jest jeszcze inna metoda, z której powinniśmy skorzystać?
Nr Dlatego funkcje te zostały wymyślone na początku ;-)
Oto dokumentacja (z Pythona 3.2.1):
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
base 256, and return a Python long with the same numeric value.
If n is 0, the integer is 0. Else:
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
LSB.
If is_signed is 0/false, view the bytes as a non-negative integer.
If is_signed is 1/true, view the bytes as a 2's-complement integer,
non-negative if bit 0x80 of the MSB is clear, negative if set.
Error returns:
+ Return NULL with the appropriate exception set if there's not
enough memory to create the Python long.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
const unsigned char* bytes, size_t n,
int little_endian, int is_signed);
Głównym powodem jest to " podkreślenie-prefiks "API polega na tym, że zależy to od implementacji Pythona long
jako tablicy słów w potędze dwubajtowej. Prawdopodobnie to się nie zmieni, ale od kiedy implementujesz API, możesz zaizolować dzwoniących przed zmianami w API Pythona.
Następnie zastosować szybki interfejs API do tych liczb, które są wystarczająco małe, a "PyLong_FromString" tylko do dużych, lub czy nie jest wystarczająco szybki ?. (Przy okazji, prawdopodobnie powinieneś oznaczyć twoje pytanie python-c-api') – dastrobu
Czy profilowałeś * i * uznałeś konwersję za wąskie gardło, czy po prostu spekulujesz? Zanim znajdziesz kompleksowe rozwiązanie prostego problemu, upewnij się, że * występuje * problem. – Bakuriu
Moje obawy są na etapie projektowania interfejsu API, a nie wynikiem profilowania implementacji. Szukam najmodniejszej metody (A) konstruowania obiektów PyLong w C - gdzie znam ich długość i które bity są ustawione; i (B) porównywania i testowania bitów w obiektach PyLong od C. Wciąganie ciągów w ogóle wydaje się bardzo nieporęczne, mam nadzieję znaleźć lepsze rozwiązanie. – aSteve