kod, który konwertuje ciągi do wskazówki w CPython 3,6 requests a UTF-8 form of the string to work with:
buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);
i tworzy ciąg reprezentacja UTF-8 po raz pierwszy, to żądany i caches it on the string object:
if (PyUnicode_UTF8(unicode) == NULL) {
assert(!PyUnicode_IS_COMPACT_ASCII(unicode));
bytes = _PyUnicode_AsUTF8String(unicode, NULL);
if (bytes == NULL)
return NULL;
_PyUnicode_UTF8(unicode) = PyObject_MALLOC(PyBytes_GET_SIZE(bytes) + 1);
if (_PyUnicode_UTF8(unicode) == NULL) {
PyErr_NoMemory();
Py_DECREF(bytes);
return NULL;
}
_PyUnicode_UTF8_LENGTH(unicode) = PyBytes_GET_SIZE(bytes);
memcpy(_PyUnicode_UTF8(unicode),
PyBytes_AS_STRING(bytes),
_PyUnicode_UTF8_LENGTH(unicode) + 1);
Py_DECREF(bytes);
}
Dodatkowe 3 bajty dotyczą reprezentacji UTF-8.
Można się zastanawiać, dlaczego ich wielkość nie zmienia się, gdy ciąg jest coś '40'
lub 'plain ascii text'
. To dlatego, że jeśli ciąg znaków jest w "compact ascii" representation, Python nie tworzy oddzielnej reprezentacji UTF-8. To returns the ASCII representation directly, który jest już ważny UTF-8:
#define PyUnicode_UTF8(op) \
(assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \
((char*)((PyASCIIObject*)(op) + 1)) : \
_PyUnicode_UTF8(op))
też może się zastanawiać, dlaczego wielkość nie zmienia się na coś takiego '1'
. To jest UFF11 FULLWIDTH DIGIT ONE, który int
traktuje jako odpowiednik '1'
.To dlatego one of the earlier steps w procesie string-to-int to
asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);
który konwertuje wszystkie białe znaki do ' '
i konwertuje wszystkie cyfry dziesiętne Unicode do odpowiednich cyfr ASCII. Ta konwersja zwraca oryginalny ciąg znaków, jeśli nie powoduje zmiany niczego, ale gdy robi zmiany, tworzy nowy łańcuch, a nowy łańcuch jest tym, który otrzymuje utworzoną reprezentację UTF-8.
chodzi o przypadkach zawijających int
na jeden ciąg wygląda to wpływa na inny, to są rzeczywiście ten sam obiekt ciągiem. Istnieje wiele warunków, w których Python będzie ponownie używał łańcuchów, równie mocno w Weird Implementation Detail Land, jak wszystko, co do tej pory omawialiśmy. W przypadku 'ñ'
ponowne użycie ma miejsce, ponieważ jest to łańcuch jednoliterowy w zakresie Latin-1 ('\x00'
- '\xff'
) oraz implementacja stores and reuses those.
Musi być powiązany z PEP393 ** Elastyczny ** Reprezentacja ciągów. – VPfB
Zanim kliknęłam na link z tweetem * wiedziałam * to Beazley właśnie to zrobił. –
yeap, to wygląda na coraz bardziej prawdopodobne, że będę musiał zaoszczędzić i pójść na jeden z jego kursów – jeremycg