Python中的id()和is

 id()返回对象的唯一身份标识,在CPython中即是对象在内存中的地址,具有非重叠生命周期的两个对象可能有相同的id。

is判断两个对象是不是同一个对象,逻辑是判断同一时刻这两个对象的id是否相同。

 代码版本:3.6.3;文档版本:3.6.6

id()本来没啥写的,我一直的理解就是返回对象在内存中的地址。

直到有一次:

class A:
    def aa(self):
        pass


class B:
    def ba(self):
        pass

    def bb(self):
        pass

    @classmethod
    def bc(cls):
        pass

    @staticmethod
    def bd():
        pass

    def __init__(self):
        pass


a = A()
b = B()
print(id(a.aa))
print(id(b.ba))
print(id(b.bb))
print(id(b.bc))
print(id(b.__init__))
print(id(b.bd))
print(id(b.__hash__))
"""
2933781120456
2933781120456
2933781120456
2933781120456
2933781120456
2933804461728
2933804434768
"""

什么?同一个类或不同类之间的实例方法、类方法、重写父类方法的id竟然都一样??这怎么可能,明明是不同的对象啊,怎么会id相同呢?

看官方文档怎么说:

id(object)

Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

 噢?具有不重叠生命周期的两个对象可能具有相同的id!

噢?id()原来返回的是对象的身份标识!在CPython中id(o)才是对象在内存中的地址!好吧id()是什么是理解了,那上面的例子为什么id一样呢?方法的生命周期不重叠?还用了同一块内存?

那也就是说,程序运行起来后,有这么一个固定的内存,当我调用实例的什么方法,它就指向什么方法,不论是哪个实例的哪个方法。用谁就指向谁,用完就拜拜。

这样的话上面的例子是明白了,可又想到,is不就是判断id吗?那id相同is岂不就返回True了?这不可能吧

class B:
    def ba(self):
        pass

    def bb(self):
        pass


b = B()
print(b.ba is b.bb)
"""False"""
print(id(b.ba) == id(b.bb))
"""True"""

 还好是false,可id明明一样啊,难道is还判断的两个对象的生命周期吗?

嗯?既然用完才拜拜,如果我站着茅坑不用,会怎么样?

class A:
    def aa(self):
        pass


class B:
    def ba(self):
        pass

    def bb(self):
        pass

    @classmethod
    def bc(cls):
        pass


a = A()
b = B()

print(id(b.ba) == id(b.bb) == id(b.bc) == id(a.aa))
print(id(a.aa))

ba = b.ba  # 把b.ba赋值给一个变量保存,相当于添加了一个引用,那就不算用完
print(id(ba))
print(id(b.bb))
print(id(a.aa))
"""
True
1746998085064
1746998085064
1746998086664
1746998086664
"""

看,之前的内存还在用着,或者说引用还存在,于是就又新找了一个内存来干这个活。

那这样也能解释is返回false了,is判断时应该是把两个对象都接收,然后再判断id。两个对象都接收存起来就保证了两个进行is比较的对象必须在同一时刻都存在,即生命周期有重叠部分,就保证了必须是同一个对象id才会相同,is判断就不会失误了。

关于id()和is的关系文档也有描述

Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; theid() function returns an integer representing its identity.

猜你喜欢

转载自blog.csdn.net/lnotime/article/details/81194633
今日推荐