我很好奇为什么用==
替换is
导致.py
在直接启动时失败。
if __name__ == '__main__':
main()
VS
if __name__ is '__main__':
main()
对象身份如何在这里工作?
我特别好奇__name__
和__main__
具有不同身份的机制,目的。
答案 0 :(得分:4)
is
表示这两个东西是同一个对象(即它们具有相同的id
)。显然,__name__
是一个与'__main__'
不同的字符串(即使它们具有相同的文本)。
一般来说,只有使用is
才真正意味着“检查这些是完全相同的对象” - 永远不要用它来表示“这些对象是平等的”。
答案 1 :(得分:1)
一些例子会使其更加明显:
In [7]: foo = 1000
In [8]: bar = 1000
In [9]: foo is bar # same value but different objects so identity test is False
Out[9]: False
In [10]: foo == bar # equality test is True
Out[10]: True
In [11]: id(foo) # both have different id's
Out[11]: 41007616
In [12]: id(bar)
Out[12]: 40841432
In [13]: foo = bar # now make foo point to the object bar
In [14]: foo is bar # now foo is bar so identity check is True
Out[14]: True
In [15]: id(bar) # matching id's
Out[15]: 40841432
In [16]: id(foo)
Out[16]: 40841432
要比较值,请使用==
检查身份使用is
要注意的是小整数-5
到256
并且字符串在cthon中被缓存和重用,所以如果你指定a = 10
和b = 10
,它们实际上都是指向同一个对象a is b
。
In [20]: a = 256
In [21]: b = 256
In [22]: a is b
Out[22]: True
In [23]: a = 257
In [24]: b = 257
In [25]: a is b
Out[25]: False
In [26]: foo = "foo"
In [27]: bar = "foo"
In [28]: foo is bar
Out[28]: True
In [29]: foo = "$bar"
In [30]: bar = "$bar"
In [31]: foo is bar # now False because it does not start with an _ or a letter
Out[31]: False
字符串仅在以underscore
或letter
开头且仅包含letters
,numbers
或underscores
时才会被缓存:
为什么__main__
失败的最后一个例子:
# first __main__ object inside locals dict, second is just a string __main__
print id(locals()['__name__']),id("__main__")
print (locals()['__name__']) is "__main__" # so not the same object
print (locals()['__name__']) == "__main__" # but == strings
if __name__ == "__main__":
print id(locals()['__name__']), id(__name__ ) # same id's
print (locals()['__name__']) is __name__ ) # same object stored in locals
140168071262544 140168071262592
False
True
140168071262544 140168071262544
True