首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么此Python字符串的大小在int转换失败时发生更改

为什么此Python字符串的大小在int转换失败时发生更改
EN

Stack Overflow用户
提问于 2017-11-02 03:21:50
回答 1查看 4.1K关注 0票数 70

tweet here

代码语言:javascript
复制
import sys
x = 'ñ'
print(sys.getsizeof(x))
int(x) #throws an error
print(sys.getsizeof(x))

对于两个getsizeof调用,我们得到74个字节,然后是77个字节。

看起来我们从失败的int调用中向对象添加了3个字节。

来自twitter的更多示例(您可能需要重新启动python才能将大小重置为74):

代码语言:javascript
复制
x = 'ñ'
y = 'ñ'
int(x)
print(sys.getsizeof(y))

77!

代码语言:javascript
复制
print(sys.getsizeof('ñ'))
int('ñ')
print(sys.getsizeof('ñ'))

74,然后是77

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-02 03:51:34

在CPython 3.6 requests a UTF-8 form of the string to work with中将字符串转换为整数的代码

代码语言:javascript
复制
buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);

字符串在第一次被请求时创建UTF-8表示形式,并使用caches it on the string object

代码语言:javascript
复制
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" representation格式的,Python就不会创建单独的UTF8表示。It returns the ASCII representation directly,它已经是有效的UTF-8:

代码语言:javascript
复制
#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))

您可能还想知道为什么像'1'这样的东西的大小不变。这是U+FF11 FULLWIDTH数字1,int认为它等同于'1'。这是因为字符串到整数过程中的one of the earlier steps

代码语言:javascript
复制
asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);

它将所有空格字符转换为' ',并将所有Unicode十进制数字转换为相应的ASCII位。如果最终没有更改任何内容,此转换将返回原始字符串,但当它进行更改时,它将创建一个新字符串,而新字符串将创建一个UTF-8表示。

至于在一个字符串上调用int看起来会影响另一个字符串的情况,它们实际上是同一个string对象。在许多情况下,Python将重用字符串,所有这些都与我们到目前为止讨论的所有情况一样坚定地存在于奇怪的实现细节领域。对于'ñ',之所以会发生重用,是因为这是一个拉丁语-1范围('\x00'-'\xff')中的单字符字符串,其实现是stores and reuses those

票数 70
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47062184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档