假设我有一个Python类,其中定义了一个eq方法来比较属性是否相等:
class Foo(object):
# init code...
def __eq__(self, other):
# usual eq code here....
我该如何比较两个Foo实例的引用相等性(即测试它们是否是同一个实例)?如果我这样做:
f1 = Foo()
f2 = Foo()
print f1 == f2
我得到True,尽管它们是不同的对象。那是 is
运算符。
print f1 is f2
- Ryhanc = 5 d = 5 c == d True c is d True id(c) 4298161480 id(d) 4298161480
f1 is f2
用于检查两个引用是否指向同一个对象。在底层实现中,它会使用 id
内置函数比较 id(f1) == id(f2)
的结果,该函数返回一个整数,保证该整数在对象的生命周期内是唯一的(但仅限于对象的生命周期内)。
在 CPython 中,这个整数恰好是对象在内存中的地址,尽管文档中提到应该假装不知道这一点(因为其他实现可能有其他方法生成 id)。
is
关键字。print f1 is f2
一些有趣的事情(我认为这是实现相关的,但在CPython中是真实存在的)与关键字is
相关,即None、True和False都是单例实例。因此,True is True
将返回True。
在CPython中,字符串也是被联合(interned)的,所以'hello world' is 'hello world'
将返回True(在正常代码中,您不应依赖此功能)。
x=123123; ...some code...; x is 123123
有时会失败。这是因为整数“对象”是动态分配的,所以有时会创建重复项。据我所知,只有整数和字符串是以这种方式动态创建的,因此它们是唯一需要担心is
会像这样表现的时间。 - Eli Collins
f1 = Foo() f2 = Foo() print f1 is f2
返回 false。参考:http://www.tutorialspoint.com/python/python_basic_operators.htm - Adam Parkin