Der Code, der Zeichenfolgen in CPython 3.6 in Ints konvertiert, fordert eine UTF-8-Form der Zeichenfolge an, mit der gearbeitet werden soll :
buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);
und die Zeichenfolge erstellt die UTF-8-Darstellung beim ersten Anfordern und speichert sie im Zeichenfolgenobjekt zwischen :
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);
}
Die zusätzlichen 3 Bytes sind für die UTF-8-Darstellung.
Sie fragen sich vielleicht, warum sich die Größe nicht ändert, wenn die Zeichenfolge so etwas wie '40'
oder ist 'plain ascii text'
. Dies liegt daran , dass Python keine separate UTF-8-Darstellung erstellt, wenn sich die Zeichenfolge in einer "kompakten ASCII" -Darstellung befindet. Es gibt die ASCII-Darstellung direkt zurück , die bereits in UTF-8 gültig ist:
(assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \
((char*)((PyASCIIObject*)(op) + 1)) : \
_PyUnicode_UTF8(op))
Sie fragen sich vielleicht auch, warum sich die Größe für so etwas nicht ändert '1'
. Das ist U + FF11 FULLWIDTH DIGIT ONE, was int
als äquivalent zu behandelt wird '1'
. Dies liegt daran, dass einer der früheren Schritte im String-to-Int-Prozess ist
asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);
Dadurch werden alle Leerzeichen in ' '
und konvertiert alle Unicode-Dezimalstellen in die entsprechenden ASCII-Stellen. Diese Konvertierung gibt die ursprüngliche Zeichenfolge zurück, wenn am Ende nichts geändert wird. Wenn jedoch Änderungen vorgenommen werden, wird eine neue Zeichenfolge erstellt, und die neue Zeichenfolge wird mit einer UTF-8-Darstellung erstellt.
In den Fällen, in denen das Aufrufen int
einer Zeichenfolge so aussieht, als würde es eine andere betreffen, handelt es sich tatsächlich um dasselbe Zeichenfolgenobjekt. Es gibt viele Bedingungen, unter denen Python Zeichenfolgen wiederverwendet, die alle genauso fest in Weird Implementation Detail Land verankert sind wie alles, was wir bisher besprochen haben. Denn 'ñ'
, geschieht die Wiederverwendung , da dies in dem Latin-1 Bereich eine Single-Zeichenkette ( '\x00'
- '\xff'
) und die Implementierung gespeichert und wieder verwendet diejenigen .