Program Tip

이 파이썬 문자열의 크기가 실패한 int 변환에서 변경되는 이유

programtip 2020. 10. 30. 20:30
반응형

이 파이썬 문자열의 크기가 실패한 int 변환에서 변경되는 이유


보내는 사람 여기 트윗 :

import sys
x = 'ñ'
print(sys.getsizeof(x))
int(x) #throws an error
print(sys.getsizeof(x))

두 번의 getsizeof호출에 대해 74 바이트와 77 바이트를 얻습니다 .

실패한 int 호출에서 객체에 3 바이트를 추가하는 것 같습니다.

twitter의 더 많은 예제 (크기를 74로 다시 설정하려면 Python을 다시 시작해야 할 수 있음) :

x = 'ñ'
y = 'ñ'
int(x)
print(sys.getsizeof(y))

77!

print(sys.getsizeof('ñ'))
int('ñ')
print(sys.getsizeof('ñ'))

74, 77.


CPython 3.6에서 문자열을 int로 변환하는 코드는 작업 할 문자열 의 UTF-8 형식을 요청합니다 .

buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);

문자열은 처음 요청 될 때 UTF-8 표현을 생성하고 이를 문자열 객체에 캐시합니다 .

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);
}

추가 3 바이트는 UTF-8 표현 용입니다.


문자열이 '40'또는 같은 경우 크기가 변경되지 않는 이유가 궁금 할 수 있습니다 'plain ascii text'. 문자열이 "compact ascii"표현 인 경우 Python은 별도의 UTF-8 표현을 생성하지 않기 때문입니다. 그것은 바로 ASCII 표현을 리턴 이미있는 유효한 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))

또한 .NET과 같은 경우 크기가 변경되지 않는 이유가 궁금 할 수 있습니다 '1'. 즉 U + FF11 전각 자리 ONE,의 int에 해당로 취급합니다 '1'. 이는 string-to-int 프로세스 의 이전 단계 중 하나

asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);

which converts all whitespace characters to ' ' and converts all Unicode decimal digits to the corresponding ASCII digits. This conversion returns the original string if it doesn't end up changing anything, but when it does make changes, it creates a new string, and the new string is the one that gets a UTF-8 representation created.


As for the cases where calling int on one string looks like it affects another, those are actually the same string object. There are many conditions under which Python will reuse strings, all just as firmly in Weird Implementation Detail Land as everything we've discussed so far. For 'ñ', the reuse happens because this is a single-character string in the Latin-1 range ('\x00'-'\xff'), and the implementation stores and reuses those.

참고URL : https://stackoverflow.com/questions/47062184/why-does-the-size-of-this-python-string-change-on-a-failed-int-conversion

반응형