zoukankan      html  css  js  c++  java
  • 我的Python学习笔记(一):==和is

    Python中对象包含的三个基本要素:id(身份标识),type(数据类型),value(值)

    • ==是用来比较两个对象的value(值)是否相等,
    • is是用来比较两个对象的id(身份标识)是否相等

    ==示例:

    x = y = [1, 2, 3]
    z = [1, 2, 3]
    print(x == y)   # True
    print(x == z)   # True
    print(x is y)   # True
    print(x is z)   # False
    
    print(id(x))    # 4416785008
    print(id(y))    # 4416785008
    print(id(z))    # 4416784504

    • x,y,z三个对象的值都是[1,2,3],所以在==的情况下都是True
    • x和y的id相同,所以x is y 为 True,而x和z的id不同,所以x is z 为 False

    is示例:

    一、整数对象

    对于整数对象,Python把一些频繁使用的整数对象缓存起来,保存到一个叫small_ints的链表中,在Python的整个生命周期内,任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。Python把这些可能频繁使用的整数对象规定在范围[-5, 256]之间的小对象放在small_ints中,但凡是需要用些小整数时,就从这里面取,不再去临时创建新的对象。

      1、当整数对象在区间[-5,256]内时,is得到的结果是True(a,b的id值相同)

    In [1]: a = 1
    In [2]: b = 1
    In [3]: print(a is b)
    True
    In [4]: print(id(a))
    4414864752
    In [5]: print(id(b))
    4414864752

      2、当整数对象不在区间[-5,256]内时,is得到的结果是False(a,b的id值不同)

    In [6]: a = 257
    In [7]: b = 257
    In [8]: print(a is b)
    False
    In [9]: print(id(a))
    4449527760
    In [10]: print(id(b))
    4449527536

      3、看懂上面两个例子后,我们接着看以下代码:

    c = 257
    
    def test():
        a = 257
        b = 257
        print(a is b)   # True
        print(a is c)   # False
        print(id(a))    # 140644774393856
        print(id(b))    # 140644774393856
        print(id(c))    # 140644774394072
    
    test()

    如果按照第2点得出的结论,257不在区间[-5,256]内,那么两个的is结果都应该为False才对,可是为什么a is b却为True呢?

    为了弄清楚这个问题,首先我们要先理解程序的代码块问题。Python程序由代码块构成,代码块作为程序的一个最小基本单位来执行。一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。在上面这段代码中,由两个代码块构成,c = 257作为一个代码块,函数test作为另外一个代码块。Python内部为了将性能进一步的提高,凡是在一个代码块中创建的整数对象,如果存在一个值与其相同的对象于该代码块中了,那么就直接引用,否则创建一个新的对象出来。Python出于对性能的考虑,但凡是不可变对象,在同一个代码块中的对象,只有是值相同的对象,就不会重复创建,而是直接引用已经存在的对象。因此,不仅是整数对象,还有字符串对象也遵循同样的原则。所以 a is b就理所当然的返回True了,而ca不在同一个代码块中,因此在Python内部创建了两个值都是257的对象。

    注:如下图所示,在PyCharm中运行如下代码,得到的结果都为True,原因就是因为在同一代码块中,值相同的对象就不会重复创建,而是直接引用已经存在的对象

    a = 1   # a和b为数值类型,在区间[-5,256]内
    b = 1
    print(a is b)   # True
    print(id(a))    # 140586619260200
    print(id(b))    # 140586619260200
    
    a = 257   # a和b为数值类型,不在区间[-5,256]内
    b = 257
    print(a is b)   # True
    print(id(a))    # 140586619294392
    print(id(b))    # 140586619294392

    二、字符及字符串对象

    当a,b为字符串对象时,python中有intern机制,它指的就是在创建一个新的字符串对象时,如果已经有了和它的值相同的字符串对象,那么就直接返回那个对象的引用,而不返回新创建的字符串对象。只包括字母数字下划线的字符串,python会对它们使用intern机制。(所以当字符串只包括字母数字下划线时,进行is操作返回True,如果包含其他字符,进行is操作则返回False)

    a = "a_1"   # a和b为字符串类型
    b = "a_1"
    print(a is b)   # True
    print(id(a))    # 4454524688
    print(id(b))    # 4454524688
    
    a = "&"     # a和b为字符串类型
    b = "&"
    print(a is b)   # True
    print(id(a))    # 4305008120
    print(id(b))    # 4305008120

    注:当a,b为单个字符对象时,进行is操作都返回True

    三、其他类型对象

    当a,b为元组,list,dict和set类型时,进行is操作结果为False

    a = (1, 2, 3)   # a和b为元组类型
    b = (1, 2, 3)
    print(a is b)   # False
    print(id(a))    # 4366076016
    print(id(b))    # 4366076416
    
    a = [1, 2, 3]   # a和b为list类型
    b = [1, 2, 3]
    print(a is b)   # False
    print(id(a))    # 4366191216
    print(id(b))    # 4366190712
    
    a = {'is' : 1, 'equal' : 2}   # a和b为dict类型
    b = {'is' : 1, 'equal' : 2}
    print(a is b)   # False
    print(id(a))    # 4365197952
    print(id(b))    # 4366187608
    
    a = ([1, 2, 3])   # a和b为set类型
    b = ([1, 2, 3])
    print(a is b)   # False
    print(id(a))    # 4366190712
    print(id(b))    # 4366191216
  • 相关阅读:
    机器学习框架之sklearn简介
    ubuntu 16.04下使用 python pip的安装问题。
    ubuntu 16.04 搭建git小型服务器
    使用config 来管理ssh的会话
    【linux】su、sudo、sudo su、sudo -i的用法和区别
    【python】确保文件写入结束
    【python】描述符descriptor
    【python】类(资料+疑惑)
    【pymongo】mongodb cursor id not valid error
    【python】继承关系和isinstance
  • 原文地址:https://www.cnblogs.com/semon-code/p/8215230.html
Copyright © 2011-2022 走看看