我正在研究Python字符串实习生机制。当我做一些这样的测试时:
# short str
list_short_str = ['0', str(0), chr(48), ''.join(['0']), '0'.join(('','')), '230'[-1:], ''+'0'+'', 'aaa0a'.strip('a')]
print("short str id:")
for item in list_short_str:
print(id(item))
# long str
list_long_str = ['hello', 'hel'+'lo', 'helloasd'[:5], ''.join(['h','e','l','l','o']), ' hello '.strip(' ')]
print("long str id:")
for item in list_long_str:
print(id(item))
我得到这样的输出:
short str id:
2450307092400
2450856182064
2450307092400
2450307092400
2450298848880
2450307092400
2450307092400
2450307092400
long str id:
2450855173808
2450855173808
2450856182256
2450856182320
2450856182192
我尝试过 IDLE、PyCharm 和 Jupyter,所有这些 IDE 都给了我相同的输出。更准确地说,对于短字符串 '0',str(0)
和 '0'.join(('',''))
使用不同的 id ,其他人也有相同的情况;对于长字符串 'hello','hello'
和 'hel'+'lo'
共享相同的 id,其他的不同。我查阅了资料,但还没有找到答案。谁能告诉我为什么?
最佳答案
在Python的String Intern机制中,当我们创建两个具有相同值的字符串时,不是为它们都分配内存,而是实际上只有一个字符串被提交到内存中。另一个仅指向同一内存位置。然而,Python 中的字符串驻留行为可能因多种因素而异,包括 Python 版本、解释器的实现以及创建字符串的上下文。因此,相同的字符串值可能并不总是被驻留,并且在某些情况下,行为可能很难预测。
Python 中同一字符串的字符串驻留结果可能不同的一个原因是,Python 仅驻留字符串文字,而不驻留运行时创建的字符串对象。 这意味着如果在编译时执行的字符串相同,则引用相同。但如果在运行时执行,则引用(id)会有所不同。
# 简而言之:
Python 中的 str() 函数在运行时执行。它将给定的对象转换为字符串表示形式。这种转换是在程序执行期间调用 str() 函数时动态发生的,而不是在程序编译期间。
join() 函数无法在编译时执行,因为列表和分隔符的值只有在运行时才知道。
'0'.join(('', '')) 表达式在 Python 中运行时执行。 该表达式使用字符串 '0' 的 join() 方法来连接元组 ('', '') 的元素。由于元组对象 ('', '') 必须在运行时存在才能让 join() 方法对其进行操作,因此表达式必须在运行时执行。 当 join() 方法的分隔符参数为非空字符串时,Python 中的 join() 方法无法在编译时执行。 因此,表达式 ''.join(['0']) 无法在编译时完全执行。但是,由于 join() 方法操作的是单元素列表,并且分隔符是空字符串,因此 Python 解释器也许能够优化表达式并在编译时部分执行它。
在#long_str中:
Python 中使用 + 运算符的字符串连接通常在运行时执行,而不是在编译时执行。这是因为字符串操作数的值可能要到运行时才知道,因此必须在那时执行串联操作。 在某些情况下,Python 解释器可能能够优化字符串连接操作并在编译时部分或全部执行它们。例如,如果 + 运算符的两个操作数都是字符串文字,并且在可以在编译时计算结果的上下文中使用表达式,则 Python 解释器可能会优化表达式并在编译时执行串联。
例如:
a =“你好”
b =“世界”
c = a + b # 这个串联将在运行时执行
d = "hello"+ "world"# 这个串联可以在编译时执行
剩下的 'helloasd'[:5], ''.join(['h','e','l','l','o']), ' hello '.strip(' ') 将在运行时执行,这就是为什么它们都有不同的 id。
希望这至少对您有一点帮助。
关于Python字符串实习生机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75719812/