• 高阶python | is 与 ==


    python版本:3.10.0

    (对于文中一些可能产生疑问的部分对应篇末有补充内容帮助读者充电,请注意“<>”提示)

    在python中,经常会搞混is与==的用法

    其实很简单,首先俩个比较都是要求比较的两者某条件相等的

    其次,is是用来比较身份标识的,==是用来比较数据值

    Python 中,对于任意的变量都具有三个基本要素:分别是 id,type,value。其中 id 为身份标识,即唯一能识别变量的标志,type 为数据类型,value 为数据值。

    例如下面的例子:

    1. a_list = [1, 2, 3]
    2. b_list = [1, 2, 3]
    3. print(a_list == b_list)
    4. print(a_list is b_list)

    True
    False

    结果为啥不一样呢?

    因为两个可变类型数据指向的对象不一样

    1. print(id(a_list))
    2. print(id(b_list))

    2793639858304
    2793643606464

    is在不可变数据的比较中慎用

    以字符串为例,在字符串的比较中,由于字符串为不可变数据类型,贸然使用is来比较两个字符串是有风险的

    我们先展示一种没翻车的版本

    1. s1 = 'i am what i am and that is all that i am'
    2. s2 = 'i am what i am' + ' and that is all that i am'
    3. print(s1 == s2)
    4. print(s1 is s2)
    5. print(id(s1))
    6. print(id(s2))

    True
    True
    2541839741264
    2541839741264

    因为这个拼接后的字符串与s1指向的字符串相同,所以s2直接指向s1指向的字符串对象,其id也相同,所以这里的is比较结果也相同。<补充3>

    而后面这个版本就翻车了

    1. s1 = 'i am what i am and that is all that i am'
    2. s2 = 'i am what i am'
    3. print('s1:', id(s1))
    4. print('s2:', id(s2))
    5. print()
    6. s2 = s2 + ' and that is all that i am'
    7. print(s1 == s2)
    8. print(s1 is s2)
    9. print('s1:', id(s1))
    10. print('s2:', id(s2))

    s1: 2061619654992
    s2: 2061619581424

    True
    False
    s1: 2061619654992
    s2: 2061619653456

     s2是后拼接的,从一开始因为赋值的字符串不一样,所以两个变量的id就不一样,即两个变量是不相同的,即使是后拼接成一样的值,其id也是不相同的,所以比较结果为false

    (同时可见字符串拼接的时候会多次申请内存地址和创建新变量,对于大量的字符串拼接,请使用join函数先把所需拼接完成后再赋值给变量)

    以整数为例,整数不同于字符串,比较简单,可以用is,但不推荐,能用==来比值达到目的就不要冒着风险使用is<整型的特性见补充4>

    1. a = 11
    2. b = 1
    3. print('a:', id(a))
    4. print('b:', id(b))
    5. print(a == b)
    6. print(a is b)
    7. print()
    8. b = 11
    9. print('a:', id(a))
    10. print('b:', id(b))
    11. print(a == b)
    12. print(a is b)

    a: 1744108323376
    b: 1744108323056
    False
    False

    a: 1744108323376
    b: 1744108323376
    True
    True

    补充内容

    1.id()的使用

    在Python中,id()函数返回对象的唯一标识符。这个标识符是一个整数,它在对象的生命周期<补充2>内保持不变。标识符可以用于比较两个对象是否相同(即是否是同一个对象)。下面是一个示例:

    1. a = [1, 2, 3]
    2. b = [1, 2, 3]
    3. print(id(a)) # 输出:140592387436232
    4. print(id(b)) # 输出:140592387436552
    5. c = a
    6. print(id(c)) # 输出:140592387436232
    7. print(a is b) # 输出:False
    8. print(a is c) # 输出:True

    在上面的示例代码中,ab虽然具有相同的值,但它们是不同的对象,因此它们的标识符不同。而将a赋值给c后,ca是同一个对象,它们的标识符相同。最后,使用is运算符可以比较两个对象是否是同一个对象。

    2.什么是对象的生命周期

    对象的生命周期指的是从对象创建到销毁的整个过程,它可以分为如下几个阶段:

    1. 创建阶段:在创建对象时,系统会为其分配一定的内存空间,并执行构造函数初始化对象的状态。

    2. 使用阶段:对象被创建后,可以通过调用对象的成员函数或访问对象的成员变量来使用它。在使用阶段中,对象可以被多次引用或修改,直到它的生命周期结束。

    3. 销毁阶段:当对象不再被引用或使用时,系统会执行析构函数销毁对象并释放其占用的内存空间。在销毁阶段中,对象的状态会被清空,并且对象所占用的内存空间会被归还给操作系统。

    在涉及复杂的对象关系时,对象的生命周期可能会因为对象间的相互引用变得复杂。为了避免对象间的循环引用,可以使用特殊的技巧,例如智能指针等,来管理对象的生命周期。

    3.python 同字符串赋值两个不同变量,为什么两个变量的id相同

    这是因为在Python中,有个特性叫做字符串常量池(string interning),即对于一些常用的字符串,Python会自动缓存这些字符串对象,每次创建相同的字符串时,实际上是返回同一个对象的引用,这个对象在内存中的位置是不变的,因此两个不同的变量赋值同一个字符串时,它们会共享同一个对象,其id也相同。但是对于不可变类型以外的对象,这个特性并不适用。

    4.python 同整型数据赋值两个不同变量,为什么两个变量的id相同

    在Python中,对于较小的整数,Python会尝试缓存这些整数以提高性能并减少内存使用。因此,当你创建一个整数时,Python会检查该整数是否已经在缓存中,如果是,则返回缓存中存在的整数的引用,而不是创建一个新的整数对象。这意味着,对于相同的整数,它们的id是相同的,因为它们实际上是同一个对象。

  • 相关阅读:
    补充:js 制作qq、微信 的表情 缺少的微信表情图片
    php反序列化
    Docker-compose
    哪些因素取决于产品设计中的质量?
    Java8实战-总结27
    单线圈无刷直流电机的电机驱动芯片GC1262E/S属于国产芯片可替代APX9262S/茂达
    Mybatis自动映射Java对象 与 MySQL8后的JSON数据
    经营分析会上,销售和财务老打架,老板很抓狂,该如何解决?
    浅析三维模型3DTile格式轻量化处理常见问题与处理措施
    李炎恢ECMAScript6 / ES6+(二)
  • 原文地址:https://blog.csdn.net/weixin_45325204/article/details/130857709