zoukankan      html  css  js  c++  java
  • 可变类型与不可变类型的特点

    1.不可变数据类型

    不可变数据类型在第一次声明赋值声明的时候, 会在内存中开辟一块空间, 用来存放这个变量被赋的值,  而这个变量实际上存储的, 并不是被赋予的这个值, 而是存放这个值所在空间的内存地址, 通过这个地址, 变量就可以在内存中取出数据了. 所谓不可变就是说, 我们不能改变这个数据在内存中的值, 所以当我们改变这个变量的赋值时, 只是在内存中重新开辟了一块空间, 将这一条新的数据存放在这一个新的内存地址里, 而原来的那个变量就不在引用原数据的内存地址而转为引用新数据的内存地址了.

    举例子:

    复制代码
    >>> x = 18
    >>> id(x)
    4497811200
    >>> id(18)
    4497811200
    >>> x = 19 
    >>> id(x)
    4497811232
    >>> id(18)
    4497811200
    >>> y = 18
    >>> id(y)
    4497811200
    >>> 
    复制代码

     一开始x = 18,开辟一块地址为4497811200的内存,即18对应的地址为4497811200,后来x = 19 ,重新开辟一块地址为4497811232的内存来放19,可以看到不变的意思是指18,和19在内存中的地址不会改变,将18赋值给y时,y指向的地址即为4497811200。

    1.可变数据类型

    结合不可变数据类型,可变数据类型就很好理解来,可变数据类型是指变量所指向的内存地址处的值是可以被改变的。

    复制代码
    >>> x = [1,2,3]
    >>> id(x)
    4501838920
    >>> y = [1,2,3]
    >>> z = [1,2,3]
    >>> id(y)
    4501838600
    >>> id(z)
    4501838664
    复制代码

    从另外一个角度来看:

    可变类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

    可变数据类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

    复制代码
    #a的值改变了,a对应的内存地址也改变了
    >>> a=1 >>> id(a) 4497810656 >>> a = 2 >>> id(2) 4497810688
    #直接对a操作,相当于拷贝了一份a的值,在其他内存地址操作,a的值不变 >>> a+1 3 >>> id(a) 4497810688 >>> a 2
    #b的值改变了,b对应的内存地址不变,第一次给b赋值的时候,给b划分一块内存空间,该空间就不变了 >>> b = [1,2,3] >>> id(b) 4501839496
    #直接对b操作,b的值改变,b指向的内存空间不变 >>> b.append(4) >>> id(b) 4501839496 >>> b [1, 2, 3, 4] >>>
    复制代码

    二.哪些是可变类型哪些是不可变类型

    不可变:Number(数字)、String(字符串)、Tuple(元组)。

    复制代码
    #整型
    a = 1
    print(id(a), type(a))
    a = 2
    print(id(a), type(a))
    
    # 4361254304 <class 'int'>
    # 4361254336 <class 'int'>
    #字符串
    b = 'anne'
    print(id(b),type(b))
    b = 'anne1995'
    print(id(b),type(b))
    
    # 4363638744 <class 'str'>
    # 4363684784 <class 'str'>
    
    #元组
    c1 = ['1','2']
    c = (1,2,c1)
    print(c,id(c),type(c))
    c1[1] = 'djx'
    print(c,id(c),type(c))
    
    # (1, 2, ['1', '2']) 4363948248 <class 'tuple'>
    # (1, 2, ['1', 'djx']) 4363948248 <class 'tuple'>

    注意:此时元组的值发生了变化而内存地址没变,但我们依然称元组为不可变类型,为什么呢?其实改的是元组中的列表,列表是可变类型,改变了值后地址依然不变。但是元组的定义就是不可变的,

    元组被称为只读列表,即数据可以被查询,但不能被修改。
    复制代码

    可以变:Set(集合)、List(列表)、Dictionary(字典)。

    复制代码
    #集合
    s = {1, 'd', '34', '1', 1}
    print(s, type(s), id(s))
    s.add('djx')
    print(s, type(s), id(s))
    
    # {1, '1', 'd', '34'} <class 'set'> 4401385256
    # {1, '1', '34', 'd', 'djx'} <class 'set'> 4401385256
    
    
    
    #列表
    list = [1,'q','qwer',True]
    print(list,type(list),id(list))
    list.append('djx')
    print(list,type(list),id(list))
    
    # [1, 'q', 'qwer', True] <class 'list'> 4401113608
    # [1, 'q', 'qwer', True, 'djx'] <class 'list'> 4401113608
    
    #字典
    tuple = (1)
    dic = {1:2}
    d = { tuple:1,'key2':'djx','key3':'li'}
    print(d,type(d),id(d))
    d['key4'] = 'haha'
    print(d,type(d),id(d))
    
    # {1: 1, 'key2': 'djx', 'key3': 'li'} <class 'dict'> 4401075976
    # {1: 1, 'key2': 'djx', 'key3': 'li', 'key4': 'haha'} <class 'dict'> 4401075976
    复制代码
  • 相关阅读:
    centos : 创建交换分区
    用法记录
    mysql日志清理
    mysql 通过查看mysql 配置参数、状态来优化你的mysql
    [WPF 自定义控件]Window(窗体)的UI元素及行为
    [WPF 自定义控件]为Form和自定义Window添加FunctionBar
    [WPF 自定义控件]让Form在加载后自动获得焦点
    [WPF 自定义控件]简单的表单布局控件
    [WPF 自定义控件]以Button为例谈谈如何模仿Aero2主题
    [WPF 自定义控件]自定义控件的代码如何与ControlTemplate交互
  • 原文地址:https://www.cnblogs.com/fan-1994716/p/13040466.html
Copyright © 2011-2022 走看看