pyr*_*rou 7 python string identity
有人可以在python 2.6.6上解释我这个奇怪的结果吗?
>>> a = "xx"
>>> b = "xx"
>>> a.__hash__() == b.__hash__()
True
>>> a is b
True # ok.. was just to be sure
>>> a = "x" * 2
>>> b = "x" * 2
>>> a.__hash__() == b.__hash__()
True
>>> a is b
True # yeah.. looks ok so far !
>>> n = 2
>>> a = "x" * n
>>> b = "x" * n
>>> a.__hash__() == b.__hash__()
True # still okay..
>>> a is b
False # hey! What the F... ?
Run Code Online (Sandbox Code Playgroud)
Kat*_*iel 18
该is运营商告诉你两个变量是否指向内存中的同一个对象.它很少有用,经常与==操作员混淆,后者告诉您两个对象是否"看起来相同".
当与短字符串文字这样的东西一起使用时,它尤其令人困惑,因为Python编译器为了提高效率而实现了这些.换句话说,当你编写"xx"编译器(发出字节码)在内存中创建一个字符串对象并导致所有文字"xx"指向它.这就解释了为什么你的前两个比较是真的.请注意,您可以通过调用id它们来获取字符串的id ,(至少在CPython上可能)它们在内存中的地址:
>>> a = "xx"
>>> b = "xx"
>>> id(a)
38646080
>>> id(b)
38646080
>>> a is b
True
>>> a = "x"*10000
>>> b = "x"*10000
>>> id(a)
38938560
>>> id(b)
38993504
>>> a is b
False
Run Code Online (Sandbox Code Playgroud)
第三是因为编译器没有拘留弦a和b,无论出于何种原因(可能是因为它是不是足够聪明,该变量n定义一次,然后永远不会被修改).
您可以在事实上力Python来实习生串通过,那么,要求它.这将为您提供大量的性能提升,并可能会有所帮助.它可能没用.
道德:不要使用is字符串文字.或者是int literals.或者在任何你不理解的地方,真的.
Gle*_*ard 12
要理解这一点,您需要了解一些不同的东西.
a is b如果a且b是同一个对象,则返回true ,而不仅仅是它们具有相同的值.字符串可以具有相同的值,但可以是该值的不同实例.a = "x",你实际在做的是创建一个字符串常量"x",然后为它指定一个名字,a.字符串常量是字面上在代码中写入的字符串,不是以编程方式计算的.字符串常量总是被实现,这意味着它们存储在一个表中以供重用:如果你说a = "a"; b = "a",它实际上与说法相同a = "a"; b = a,因为它们将使用相同的实习字符串"a".这就是为什么第一个a is b是真的.a = "x" * 2,Python编译器实际上正在优化它.它在编译时计算字符串 - 它生成的代码就像你写的一样a = "xx".因此,结果字符串"xx'被实现.这就是为什么第二个a is b是真的.a = "x" * n,Python编译器在编译时不知道n是什么.因此,它必须实际输出字符串"x",然后在运行时执行字符串乘法.因为这是在运行时执行,而"x"被拘留得到的字符串"xx"是不是.因此,这些字符串中的每一个都是不同的实例"xx",因此最终的结果a is b为False.你可以自己看出差异:
def a1():
a = "x"
def a2():
a = "x" * 2
def a3():
n = 2
a = "x" * n
import dis
print "a1:"
dis.dis(a1)
print "a2:"
dis.dis(a2)
print "a3:"
dis.dis(a3)
Run Code Online (Sandbox Code Playgroud)
在CPython 2.6.4中,这输出:
a1:
4 0 LOAD_CONST 1 ('x')
3 STORE_FAST 0 (a)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
a2:
6 0 LOAD_CONST 3 ('xx')
3 STORE_FAST 0 (a)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
a3:
8 0 LOAD_CONST 1 (2)
3 STORE_FAST 0 (n)
9 6 LOAD_CONST 2 ('x')
9 LOAD_FAST 0 (n)
12 BINARY_MULTIPLY
13 STORE_FAST 1 (a)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
最后,请注意,a = intern(a); b = intern(b)如果字符串,您可以说创建实习版本,这将保证a is b是真的.如果您只想检查字符串相等性,那么只需使用a == b.
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |