其他
What the f*ck Python!
>>> id(a)
140420665652016
>>> id("some" + "_" + "string") # 注意两个的id值是相同的.
140420665652016
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True # 3.7 版本返回结果为 False.
当在同一行将 a
和 b
的值设置为 "wtf!"
的时候, Python 解释器会创建一个新对象,同时引用第二个变量。
如果你在不同的行上进行赋值操作, 它就不会 “知道” 已经有一个 wtf!
对象 (因为 "wtf!"
包含叹号,是无法被隐式驻留),它是一种编译器优化, 特别适用于交互式环境。
什么是驻留?由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象,而不是每次都创建一个新对象,这种行为被称作字符串的驻留。
发生驻留之后, 许多变量可能指向内存中的相同字符串对象,从而达到节省内存的目的。
所有长度为 0 和长度为 1 的字符串都被驻留. 字符串在编译时被实现, 'wtf'
将被驻留, 但是''.join(['w', 't', 'f'])
将不会被驻留字符串中只包含字母,数字或下划线时将会驻留。所以 'wtf!'
由于包含!
而未被驻留。可以在这里找到 CPython 对此规则的实现。
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False # 3.7 版本返回结果为 True
对于 'a' * 21 为啥返回 False,这其实涉及到常量折叠的技术,这种技术是 Python 中的一种窥孔优化技术,在编译时表达式 'a'*20
会被替换为 'aaaaaaaaaaaaaaaaaaaa'
以减少运行时的时钟周期,只有长度小于 20 的字符串才会发生常量折叠。
这个项目有万人 Star,相信 What the f*ck Java 开源项目也不远了,感兴趣的小伙伴可以整一个,整完把地址给我,我帮你推荐一下。
每天推荐一个有趣、好玩且可能你会用到的 GitHub 项目。