zoukankan      html  css  js  c++  java
  • python基础(8)python中is和==的区别详解

    前置知识点

    当我们创建一个对象时,我们要知道它内部干了些什么

    • 1.创建了一个随机id,开辟了一片内存地址
    • 2.自动声明了这个对象的类型type
    • 3.给这个对象赋值value
       

    小例子

    a = 1
    print(id(1))
    print(id(a))
    print(type(a))
    

    结果

    4470700832
    4470700832
    <class 'int'>
    

    可以明显看出数字1的内存地址跟对象a的内存地址是一样的,a = 1的原理是首先内存中有一个id=4470700832type=intvalue=1的对象,然后创建a对象指向1,此时a的id、type、value跟1的一样
     

    is和==的区别

    上面分析了创建对象的整个内存过程,那么接下来理解is和==的区别就好多了

    • is:用于判断两个变量引用对象是否为同一个,既比较对象的地址。
    • ==:用于判断引用变量引用对象的值是否相等,默认调用对象的 __eq__()方法。
    >>> a = 257
    >>> b = 257
    >>> id(a)
    140204598140720
    >>> id(b)
    140204598140400
    >>> print(a is b)
    False
    >>> print(a == b)
    True
    

    根据我们上面讲解的,a的地址和b的地址应该跟257的地址相同,但是现在显然不同,这是为什么呢?下面会说明
     

    整数缓存问题

    Python 仅仅对比较小的整数对象进行缓存(范围为[-5, 256])缓存起来,而并非是所有整数对象。需要注意的是,这仅仅是在命令行中执行,而在Pycharm或者保存为文件执行,结果是不一样 的,这是因为解释器做了一部分优化(范围是[-5,任意正整数])。
     

    总结

    • is 比较两个对象的 id 值是否相等,是否指向同一个内存地址
    • == 比较的是两个对象的内容是否相等,值是否相等
    • 小整数对象[-5,256]在全局解释器范围内被放入缓存供重复使用
    • is 运算符比 == 效率高,在变量和 None 进行比较时,应该使用 is。
       

    字符串驻留机制

    什么是字符串驻留?

    字符串驻留是一种仅保存一份相同且不可变字符串的方法。

    基本原理
    系统维护interned字典,记录已被驻留的字符串对象。
    当字符串对象a需要驻留时,先在interned检测是否存在,若存在则指向存在的字符串对象,a的引用计数减1;
    若不存在,则记录a到interned
     

    为什么要字符串驻留?

    • 显而易见,节省大量内存
    • 在字符串比较时,非驻留比较效率o(n),驻留时比较效率o(1)。

       

    字符串什么时候驻留?

    1.字符串只在编译时进行驻留,而非运行时。

    >>> a = "hello" + "world"
    >>> a is "helloworld"
    True
    >>> a = "hello"
    >>> b = "world"
    >>> a + b is "helloworld"
    False
    

    2. 字符串长度为0和1时,默认都采用了驻留机制。

    >>> a = "*"
    >>> b = "*"
    >>> a is b
    True
    >>> a = "**"
    >>> b = "**"
    >>> a is b
    False
    

    3. 字符串>1时,且只含大小写字母、数字、下划线时,才会默认驻留。

    >>> a = "hello1_"
    >>> b = "hello1_"
    >>> a is b
    True
    >>> a = "hello!"
    >>> b = "hello!"
    >>> a is b
    False
    

    4. 用乘法得到的字符串,有以下2种情况。

    • a. 乘数为1时,详见Python代码:
    # 乘数=1,仅含大小写字母、数字、下划线驻留
    >>> a = "abcdefghijklmnopqrstuvwxyz1234567890_ABCDXYZ"
    >>> b = a * 1
    >>> a is b
    True
    
    # 乘数=1,含其他字符,长度≤1,默认驻留
    >>> a = "#"
    >>> b = "#" * 1
    >>> a is b
    True
    
    # 乘数=1,含其他字符,长度>1,则不驻留
    >>> a = "##"
    >>> b = "##" * 1
    >>> a is b
    False
    
    • b.乘数>=2时,详见Python代码:
    ## 仅含有大小写字母、数字、下划线,默认驻留
    >>> a = "hellohellohellohellohellohellohello"
    >>> b = "hello"*7
    >>> a is b
    True
    
    # 含其他字符串,默认不驻留
    >>> a = "&&&&"
    >>> b = "&"*4
    >>> a is b
    False
    

    5. 字符串被sys.intern() 指定驻留。

    >>> from sys import intern
    >>> a = intern("hello#!")
    >>> b = intern("hello#!")
    >>> a is b
    True
    >>> 
    

    最后,当不满足标识符规则时,则不会启用驻留机制,当然这只出现在命令行中,如果你使用pycharm则不会出现这样的情况,pycharm内部已经帮我们做了处理

  • 相关阅读:
    为https请求配置ssl(不用keystore,直接用证书,rsa私钥,java代码)
    http请求对于List类型参数的处理
    java中string转ByteBuffer
    lua for循环如何从第0位开始
    lua中的cjson简单使用
    mongodb返回方便读的数据
    markdown简单插入图片
    #问题#java报Annotation processing is not supported for module cycles
    #问题#java报can't create non-static inner class instance
    git commit+push的完整步骤
  • 原文地址:https://www.cnblogs.com/jiakecong/p/14508642.html
Copyright © 2011-2022 走看看