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

时间:2014-08-16 00:03:50

标签: python main identity

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

if __name__ == '__main__':
    main()

VS

if __name__ is '__main__':
    main()

对象身份如何在这里工作?

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

2 个答案:

答案 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

要注意的是小整数-5256并且字符串在cthon中被缓存和重用,所以如果你指定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开头且仅包含lettersnumbersunderscores时才会被缓存:

为什么__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