• Python教程: ‘==‘ 与‘is‘ 以及它们背后的小秘密


    比较判断逻辑是在代码中经常使用的,在Python中常用 '==' 和 is 来做比较判断。

    • == : 双等号是用来比较变量所指向内存单元中的值是否相等,它只关心值,并不在意值的内存地址,也就是说可以是两个不同内存地址的值相等。
    • is : 它用来比较两个变量是不是指向同一个内存单元,虽然它也可以比较值,但是它更加关心的是内存地址是否一样,当然内存地址一样值也就是一样的。

    关于整数

    # 按照逻辑,下面的代码很正常
    >>> a = 1
    >>> b = 1
    >>> a == b
    True
    >>> a is b
    True
    >>> id(a)
    1570522768
    >>> id(b)
    1570522768
    # 下面就是颠覆认知的时刻
    >>> a = 1000
    >>> b = 1000
    >>> a == b
    True
    >>> a is b
    False
    >>> id(a)
    81183344
    >>> id(b)
    81183376
    

    是的,两个相同值的变量,内存地址不一样了。当然产生这个现象的前提条件是用python命令行去执行,而不是用pycharm之类的编辑器。其根本原因也就是python解释器的问题,涉及到python的垃圾回收机制。上面现象的原因是因为一个叫做小整数对象池的东西。

    Python为了优化速度,会把 [-5, 256] 之间的数据提前存放在小整数池中,如果程序使用到小整数池中的数据,是不会开辟新的内存空间去创建,而是指向对象池中的同一份数据,也就是说有N个变量等于1的话,那么这N个变量的内存地址都会指向小整数池中的1位置。小整数池的使用是为了避免整数频繁申请和销毁内存空间。小整数池是提前建立好的,不会被垃圾回收。

    当数据超出小整数池后,也就是范围到了大整数对象池中了,系统每次都会申请一块新内存来存储数据,这个'is'不等于'=='的现象也就不存在了。

    pycharm中,每次运行是所有代码都加载到内存中,属于一个整体,并不存在这个现象。

    关于字符串

    '''
    学习中遇到问题没人解答?小编创建了一个Python学习交流群:857662006
    寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    # 先来个正常的
    >>> a = 'qwe'
    >>> b = 'qwe'
    >>> a == b
    True
    >>> a is b
    True
    >>> id(a)
    81797024
    >>> id(b)
    81797024
    #  感觉没什么变化,那就加长一些
    >>> a = 'q' * 20
    >>> b = 'q' * 20
    >>> a is b
    True
    >>> a == b
    True
    # 在长点就不一样了
    >>> b = 'q' * 21
    >>> a = 'q' * 21
    >>> a is b
    False
    >>> a == b
    True
    >>> id(a)
    81811696
    >>> id(b)
    81811600
    

    产生原因:Python的intern机制。

    简单理解有点像缓存的意思,当需要使用相同的字符串时(变量赋值),直接从缓存中拿出来用而不是重新创建,这样可以避免频繁的创建和销毁,提升效率,节约内存。缺点是拼接字符串,对字符串修改之类的影响性能。因为是不可变的,所以对字符串修改不是inplace操作,而是新建对象。这也就是拼接字符串的时候不建议是用 '+' 方法,而是推荐用join 函数,join函数是先计算出所有字符串的长度,然后一一拷贝,而只创建一次对象。每个'+'方法都是创建一次新对象。当字符串长度超过20时,也不会使用intern机制。

    并不是所有的字符串都会采用intern机制。只包含下划线,字母(包含大小写),数字的字符串才会被intern。空格和一些特殊字符都不在内。也就是说字符串中如果包含空格和其他一些特殊符号(除去下划线),python都不会应用intern机制,而是直接开辟新的内存空间去存储。

    # 注意下面这种看似合理的字符串intern
    >>> 'ab' + 'c' is 'abc'         #  这里的字符串,'ab' + 'c' 是在complie time 求值的,被替换成了'abc'
    True
    >>> n1 = 'ab'
    >>> n2 = 'abc'
    >>> n1 + 'c' is n2               # n1 + 'c'  是在run-time拼接,导致没有被自动intern
    False
    >>> n1 + 'c' is 'abc'
    False
    >>> n1 + 'c' == 'abc'
    True
    >>> n1 + 'c' == n2
    True
    
  • 相关阅读:
    为什么我要学习qt quick
    geometory Intersect
    删除kubernetes节点的正确姿势
    乞丐版docker私有仓库搭建
    kubernetes集群中由于某些原因导致etcd节点没有删干净,需要手动清理etcd节点
    k8s coredns设置上游name server
    虚拟机架设koolshare软路由
    文件类型特征码
    深入字节码 -- 计算方法执行时间
    启迪思维:二叉树
  • 原文地址:https://www.cnblogs.com/xxpythonxx/p/16348587.html
Copyright © 2020-2023  润新知