为什么对象__name__和__main__在Python中有不同的标识?



我很好奇为什么用is替换==会导致.py在直接启动时失败。

if __name__ == '__main__':
    main()

if __name__ is '__main__':
    main()

对象标识在这里是如何工作的?

我特别好奇__name____main__具有不同身份的机制和目的。

is表示两者是同一对象(即它们具有相同的id)。显然,__name__是一个不同于'__main__'的字符串(即使它们有相同的文本)。

一般来说,只有当你真正的意思是"检查这些是完全相同的对象"时才使用is——永远不要用它来表示"这些对象是相等的"。

下面的几个例子会让它更明显:

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

需要注意的是,小整数-5256和字符串在python中被缓存和重用,所以如果你分配a = 10b = 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

字符串只有在以underscoreletter开头并且只包含letters, numbersunderscores时才会被缓存:

__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

相关内容

  • 没有找到相关文章

最新更新