字符串分裂的身份怪癖()

2024-06-09 02:02:25 发布

您现在位置:Python中文网/ 问答频道 /正文

>>> 'hi'.split()[0] is 'hi'
    True    
>>> 'hi there'.split()[0] is 'hi'
    False
>>> 'hi there again'.split()[0] is 'hi'
    False

我的假设是:

第一行只有一个split元素,而其他两行有多个元素。我相信,虽然像str这样的Python原语是按函数中的值存储在内存中的,但是会有跨函数的单独分配来简化内存管理。我认为split()就是其中一个函数,它通常会分配新的字符串。但它也处理不需要任何拆分的输入的边缘情况(例如'hi'),其中只返回原始字符串引用。我的解释正确吗?你知道吗


Tags: 函数内存字符串falsetrue元素is情况
3条回答

I believe that while Python primitives like str are stored in memory by value within a function, there will be separate allocations across functions to simplify memory management.

Python的对象分配不是这样的。“原语”并不是一个真正的概念,除了字节码编译器为合并常量所做的一些事情之外,两个对象是在同一个函数中创建还是在不同的函数中创建并不重要。你知道吗

没有比指向源代码更好的答案了,所以here it is

Py_LOCAL_INLINE(PyObject *)
STRINGLIB(split_whitespace)(PyObject* str_obj,
                           const STRINGLIB_CHAR* str, Py_ssize_t str_len,
                           Py_ssize_t maxcount)
{
    ...
#ifndef STRINGLIB_MUTABLE
        if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
            /* No whitespace in str_obj, so just use it as list[0] */
            Py_INCREF(str_obj);
            PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
            count++;
            break;
        }

如果它找不到任何可拆分的空白,它只会重用返回列表中的原始string对象。这只是这个函数如何编写的一个怪癖,在其他Python版本或非标准Python实现中,您不能指望它以这种方式工作。你知道吗

就像我在评论中说的:

'hi there again'.split()[0] == 'hi'

>>True

事实上你的问题有点确定了-这是一个身份。你知道吗

Python中的所有数据都是通过引用存储的。(C实现中的PyObject*)您发现.split()只是在没有找到分隔符时返回self作为优化。当找到分隔符时,它必须为每个部分创建单独的字符串对象,因此它们是单独的对象。你知道吗

(与Java不同,Java的“原语”和“引用/类类型”的数据类型明显不同,它们的行为也不同)

相关问题 更多 >