Python中无小写字符的字符串调用upper()为何与原串id不同?
为什么全大写字符串调用upper()后和原字符串id不同
upper() 返回值规则
upper() 方法会返回给定字符串的大写形式,将所有小写字符转换为大写;如果字符串中不存在小写字符,则返回原始字符串。
按照上述规则,如下代码中x是全大写字符串,调用upper()本该返回原始字符串赋值给y,但实际运行时二者id并不一致:
x = 'PYTHONCORE' y = x.upper() print(id(y), id(x))
运行输出:
1925088550320 1925088583152
原因说明
这里的规则表述容易产生误解:所谓「不存在小写字符时返回原始字符串」,指的是返回值的内容和原字符串完全相等,不是语言层面强制要求必须返回内存地址完全相同的原对象。
- Python中字符串是不可变类型,
upper()的执行逻辑是先逐字符扫描整个字符串,检查是否存在需要转换的小写字符:如果存在小写字符,就创建新的全大写字符串返回;如果不存在需要转换的字符,具体返回原对象还是内容相同的新对象,属于解释器的内部实现细节,没有强制规范。 - 你测试的场景里,当前运行的Python解释器在扫描完字符串确认无小写字符后,直接创建了一个内容和原串完全一致的新字符串返回,因此
x和y指向不同内存地址,id自然不同。 - 这类行为完全符合Python的设计逻辑:对于不可变对象,值相等的前提下是否复用同一个内存地址,属于解释器的可选优化策略(比如大家熟悉的短字符串驻留,也只会在特定触发条件下生效,不会覆盖所有值相等的字符串场景),不属于对外承诺的固定行为。
你可以自行验证:只要字符串包含需要转换的小写字符,upper()一定会返回新对象;如果是无小写字符的字符串,是否返回同id对象在不同Python版本、不同运行环境下结果可能不一样,不能依赖这个特性写代码。
内容的提问来源于stack exchange,提问作者Shiva Gupta
相关产品推荐
相关产品推荐

