精华内容
下载资源
问答
  • python精讲 不可变对象与可变对象

    千次阅读 2020-07-22 15:46:35
    文章目录对象变对象不可变对象变对象不可变对象 对象 Python 中的变量不是装有对象的“容器”,而是贴在对象上的“标签”。 真正的存贮位置是内存中 在python中,可变对象包括:list、set、dict、自定义对象...

    对象(object)

    cpu,内存,硬盘之间的关系:

    CPU与内存间的工作关系为:
    当我们在计算机上执行一个程序时,首先由输入设备向CPU发出操作指令,

    CPU接收到操作指令后,硬盘中对应的程序指令被直接加载到内存中,此

    后,CPU再对内存进行寻址操作,将加载到内存中的指令翻译出来,而后

    发送操作信号给操作控制器,实现程序的运行或数据的处理。

    对象

    • 对象即在内存中存储数据的一块区域
    • Python 中的变量不是装有对象的“容器”,而是贴在对象上的“标签”。
      真正的存贮位置是内存中
    - 每个对象都有三个要素:id(标识)(唯一性,每个对象都有唯一的id)
    					  type(类型)(决定对象的功能)
    					  value(值)(对象存储的数据值)
    

    对象

    • 在python中,可变对象包括:list、set、dict、自定义对象;
    • 不可对对象包括:int、float、str、bool、tuple等。
    • 不可变对象步允许自身内容进行修改。如果我们队一个不可变对象进行赋值,实际上是生成一个新对象,再让变量指向这个对象。哪怕这个对象简单到只是数字0和1

    每个对象在内存中都会存储三个数据:
    1.id(标识)
    2.type(类型)
    3.value(值)

    可变对象与不可变对象

    可变对象

    而可变对象即指在对象不改变的前提下让对象的数据发生改变
    即值发生改变但是 对象 未发生改变,例如 标识id 不会发生改变

    a = [1,2,3]
    print('修改前',a,id(a))
    a[0] = 4  #改变了值
    print('修改后',a,id(a))  #但是id未变
    
    修改前 [1, 2, 3] 1221617771648
    修改后 [4, 2, 3] 1221617771648
    

    对象没有发生改变而值发生改变
    a[0]=4

    重新赋值则开辟新的内存块存储新的值,顶替原来的对象和值
    在这里插入图片描述

    a = [1,2,3]
    print('修改前',a,id(a))
    a = [2,3,4]  #重新赋值即重新建立一个a,所以这个a不是原来的a,
                 #而是新生的a
    print('修改后',a,id(a))  #所以内存中重新开辟空间,对象发生改变
    
    修改前 [1, 2, 3] 2057897038528
    修改后 [2, 3, 4] 2057897038720
    

    因为对象不可变,所以为了提高效率,Python 会使用一些公用的对象:

    a = 1
    print('a', id(a))
    b = 1
    print('b', id(b))
    print(a == b)
    print(a is b)
    c = 'hello world'
    print('c', id(c))
    d = 'hello world'
    print('d', id(d))
    print(c == d)
    print(c is d)
    

    输出:

    a 4423761776
    b 4423761776
    True
    True
    c 4430180912
    d 4430180912
    True
    True
    

    这里顺便提一下 is 这个操作符。它和 == 的区别在于:== 只判断“值”是不是相等,而 is 则判断是否为同一个对象,也就是地址一致。比如:

    a = 2
    b = 2.0
    print(a == b)
    print(a is b)
    

    输出:

    True
    False
    

    不可变对象

    不可变对象不允许对自身内容进行修改。如果我们对一个不可变对象进行赋值,实际上是生成一个新对象,再让变量指向这个对象。:
    即重新赋值

    a = 0
    print('a', id(a))
    a = 1
    print('a', id(a))
    

    输出:

    a 4463151440
    a 4463151472
    

    在这里插入图片描述

    展开全文
  • Python的可不可变数据类型

    万次阅读 多人点赞 2015-11-16 13:13:19
    python的可不可变数据类型

    python的可变与不可变数据类型


        初学python的时候,可能会有很多疑惑,尤其是最先接触的所谓的“可变数据类型”和“不可变数据类型”。python与C/C++不一样,它的变量使用有自己的特点,当初学python的时候,一定要记住“一切皆为对象,一切皆为对象的引用”这句话,其实这个特点类似于JAVA,所以在python里面大家也不用担心类似于C/C++中的指针的复杂问题。下面本文将对python里面的“可变数据类型”和“不可变数据类型”进行分析。

        首先,我们需要知道在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。

        然后,我们以int和list为例,来看看“可变数据类型”和“不可变数据类型”到底有什么区别。

    (1)不可变数据类型分析。先来看一段程序:

    >>> x = 1
    >>> id(x)
    31106520
    >>> y = 1
    >>> id(y)
    31106520
    >>> x = 2
    >>> id(x)
    31106508
    >>> y = 2
    >>> id(y)
    31106508
    >>> z = y
    >>> id(z)
    31106508
    >>> x += 2
    >>> id(x)
    31106484 

        上面这段程序都是对不可变数据类型中的int类型的操作,id()查看的是当前变量的地址值。我们先来看x = 1和y = 1两个操作的结果,从上面的输出可以看到x和y在此时的地址值是一样的,也就是说x和y其实是引用了同一个对象,即1,也就是说内存中对于1只占用了一个地址,而不管有多少个引用指向了它,都只有一个地址值,只是有一个引用计数会记录指向这个地址的引用到底有几个而已。当我们进行x = 2赋值时,发现x的地址值变了,虽然还是x这个引用,但是其地址值却变化了,后面的y = 2以及z = y,使得x、y和z都引用了同一个对象,即2,所以地址值都是一样的。当x和y都被赋值2后,1这个对象已经没有引用指向它了,所以1这个对象占用的内存,即31106520地址要被“垃圾回收”,即1这个对象在内存中已经不存在了。最后,x进行了加2的操作,所以创建了新的对象4,x引用了这个新的对象,而不再引用2这个对象。

        那么为什么称之为不可变数据类型呢?这里的不可变大家可以理解为x引用的地址处的值是不能被改变的,也就是31106520地址处的值在没被垃圾回收之前一直都是1,不能改变,如果要把x赋值为2,那么只能将x引用的地址从31106520变为31106508,相当于x = 2这个赋值又创建了一个对象,即2这个对象,然后x、y、z都引用了这个对象,所以int这个数据类型是不可变的,如果想对int类型的变量再次赋值,在内存中相当于又创建了一个新的对象,而不再是之前的对象。从下图中就可以看到上面程序的过程。



    图1 python不可变数据类型分析

        从上面的过程可以看出,不可变数据类型的优点就是内存中不管有多少个引用,相同的对象只占用了一块内存,但是它的缺点就是当需要对变量进行运算从而改变变量引用的对象的值时,由于是不可变的数据类型,所以必须创建新的对象,这样就会使得一次次的改变创建了一个个新的对象,不过不再使用的内存会被垃圾回收器回收。

    (2)可变数据类型分析。下面同样先看一段程序。

    >>> a = [1, 2, 3]
    >>> id(a)
    41568816
    >>> a = [1, 2, 3]
    >>> id(a)
    41575088
    >>> a.append(4)
    >>> id(a)
    41575088
    >>> a += [2]
    >>> id(a)
    41575088
    >>> a
    [1, 2, 3, 4, 2]

        从上面的程序中可以看出,进行两次a = [1, 2, 3]操作,两次a引用的地址值是不同的,也就是说其实创建了两个不同的对象,这一点明显不同于不可变数据类型,所以对于可变数据类型来说,具有同样值的对象是不同的对象,即在内存中保存了多个同样值的对象,地址值不同。接着来看后面的操作,我们对列表进行添加操作,分别a.append(4)和a += [2],发现这两个操作使得a引用的对象值变成了上面的最终结果,但是a引用的地址依旧是41575088,也就是说对a进行的操作不会改变a引用的地址值,只是在地址后面又扩充了新的地址,改变了地址里面存放的值,所以可变数据类型的意思就是说对一个变量进行操作时,其值是可变的,值的变化并不会引起新建对象,即地址是不会变的,只是地址中的内容变化了或者地址得到了扩充。下图对这一过程进行了图示,可以很清晰地看到这一过程。


    图2 python可变数据类型分析

        从上述过程可以看到,可变数据类型是允许同一对象的内容,即值可以变化,但是地址是不会变化的。但是需要注意一点,对可变数据类型的操作不能是直接进行新的赋值操作,比如说a = [1, 2, 3, 4, 5, 6, 7],这样的操作就不是改变值了,而是新建了一个新的对象,这里的可变只是对于类似于append、+=等这种操作。

        总之,用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。”

        最后,大家主要区分开什么是变量值的变化、什么是变量引用的对象地址的变化这些概念就很清楚了,千说万说都不如自己动手写一些程序测试一下看看来得实在,所以建议大家有什么疑惑可以自己写一些基本的程序测试一下便知道结果。如果大家有新的意见,欢迎补充,谢谢。
    展开全文
  • python 可变数据不可变数据解析

    千次阅读 2013-08-14 10:00:20
    python 的数据类型和C不一样,有一种类型:可类型 (mutable)和不可变类型(immutable) Python中所有变量都是值的引用,也就说变量通过绑定的方式指向其值。 而这里说的不可变指的是值的不可变。 对于不可变类型...

    python 的数据类型和C不一样,有一种类型:可变类型 (mutable)和不可变类型(immutable)

    Python中所有变量都是值的引用,也就说变量通过绑定的方式指向其值。 而这里说的不可变指的是值的不可变。 对于不可变类型的变量,如果要更改变量,则会创建一个新值,把变量绑定到新值上,而旧值如果没有被引用就等待垃圾回收。不可变的类型还有一个特性,就是可以计算其hash值,这样才能进一步作为字典的key。可变类型数据对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

    不可变类型包括:int string float tuple

    可变类型包括:list dict

    展开全文
  • Python中的可变对象不可变对象

    千次阅读 2017-12-11 10:25:31
    python变量赋值(可不可变)知识点:python中,万物皆对象。  python中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址。 Python在heap中分配的对象分成两类:可变对象不可变对象。所谓可...

    python变量赋值(可变与不可变)

    知识点:python中,万物皆对象。
         python中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址。
    Python在heap中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如list。而不可变的对象则相反,表示其内容不可变。

    不可变对象:int,string,float,tuple
    可变对象 :list,dictionary
    一、不可变对象

    由于Python中的变量存放的是对象引用,所以对于不可变对象而言,尽管对象本身不可变,但变量的对象引用是可变的。运用这样的机制,有时候会让人产生糊涂,似乎可变对象变化了。如下面的代码:

    i=73
    i=i+2
    不可变对象不变,引用变了
    这里写图片描述

    不可变的对象的特征没有变,依然是不可变对象,变的只是创建了新对象,改变了变量的对象引用。
    看看下面的代码,更能体现这点的。

    print(id(100)) # 1362346144
    a = 100
    print(id(a)) # 1362346144
    b = 100
    print(id(b)) # 1362346144
    但如果变成258则id就有变化

    print(id(258)) # 1659053321968
    a = 258
    print(id(a)) # 1659053321968
    b = 258
    print(id(b)) # 1659053319280
    为何不一样了?

    (答案转自知乎问题:为什么Python有相同的不可变对象id不同?或者知乎原答案)

    二、可变对象
    这里写图片描述
    其对象的内容是可以变化的。当对象的内容发生变化时,变量的对象引用是不会变化的。

    关于此问题的大坑:函数默认参数的使用
    先定义一个函数,传入一个list,添加一个END再返回:
    def add_end(L=[]):
    L.append(‘END’)
    return L
    当你正常调用时,结果似乎不错:

    >>> add_end([1, 2, 3])
    [1, 2, 3, 'END']
    >>> add_end(['x', 'y', 'z'])
    ['x', 'y', 'z', 'END']

    当你使用默认参数调用时,一开始结果也是对的:

    >>> add_end()
    ['END']

    但是,再次调用add_end()时,结果就不对了:

    >>> add_end()
    ['END', 'END']
    >>> add_end()
    ['END', 'END', 'END']

    很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了’END’后的list。
    原因解释如下:
    Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
    所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
    要修改上面的例子,我们可以用None这个不变对象来实现:

    def add_end(L=None):
        if L is None:
            L = []
        L.append('END')
        return L

    现在,无论调用多少次,都不会有问题:

    >>> add_end()
    ['END']
    >>> add_end()
    ['END']

    为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

    作者:五秋木
    链接:http://www.jianshu.com/p/b690422ec02a
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • (转)Java 可变对象不可变对象

    千次阅读 2018-07-23 15:44:18
     不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象数据,也即对象属性值)就不能改变,反之即为可变对象(Mutable Objects)。  不可变对象的类即为不可变类(Immutable Class)。Java平台类库中包含...
  • 将python3的基本数据类型有六种: Number(int, float, bool, complex),String, List, Tuple, Dictionary, Set...不可变数据类型:Number, String, Tuple 两者区别: >>> a = [1, 2] >>> print...
  • Python数据类型有哪些,哪些是可类型,哪些是不可变类型? 类型: 整数int 字符串str 浮点数float 布尔型bool 列表list 字典dict 集合set 元组tuple 可类型:就是这个数据类型的值在不改变这一块内存空间,而去...
  • python中可变数据类型与不可变数据类型小结

    万次阅读 多人点赞 2018-12-13 11:52:59
    一、python中数据类型(红色为可变类型) 1、字符串 str 2、布尔类型 bool 3、整数 int  4、浮点数 float 5、数字 (int和float)6、列表 list 7、元组 tuple8、字典 dict 9、日期 date 二、可变类型 ...
  • 周六写一篇关于python 的博客(可 :地址传递 不可变:值传递)
  • 初学python的时候,可能会有很多疑惑,尤其是最先接触的所谓的“可变数据类型”和“不可变数据类型”。python与C/C++不一样,它的变量使用有自己的特点,当初学python的时候,一定要记住“一切皆为对象,一切皆为...
  • 学习Python首先我们要知道Python变量保存的是值引用 也可以说:变量是对内存及其地址的抽象 Python:一切变量都是对象 ...变量的每一次初始化,都开辟了一个新的空间,将新内容的地址赋值给...
  • Java中的String为什么是不可变的? -- String源码分析

    万次阅读 多人点赞 2014-01-15 22:07:12
    什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的...
  • python对象的内容可变不可变:  因为,变量无类型,如n= 1 #指向int数据类型的变量n,而n没有类型  所以,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象   python函数参数传递...
  • 数据、数据元素、数据项、数据对象的介绍和理解

    万次阅读 多人点赞 2019-06-18 20:57:43
    对于数据 数据对象 数据元素 数据项 这四个概念 理解的不是很好 我先说下课本上是怎么说的 然后再根据自己和网上的理解说下更直白的解释 数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,...
  • 为什么String要设计成不可变的?

    万次阅读 多人点赞 2013-11-18 20:30:03
    翻译人员: 铁锚 翻译日期: 2013年11月18日 原文链接: Why ... 在Java中将String设计成不可变的是综合考虑到各种因素的结果,想要理解这个问题,需要综合内存,同步,数据结构以及安全等方面的考虑.
  • 我们可以通过 id() 这个函数来查看对象的内存地址,如果两个对象的内存地址相同则代表是可类型,如果不相同则代表不可变类型 a = 1 print(id(a)) # 140716959916880 a = 2 print(id(a)) # 140716959916912 str1 =...
  • java安全编码指南之:Mutability可变

    万次阅读 2020-09-03 09:20:15
    文章目录简介可变对象不可变对象创建mutable对象的拷贝为mutable类创建copy方法不要相信equals不要直接暴露可修改的属性public static fields应该被置位finalpublic static final field 应该是不可变的 ...
  • Java数据类型—String进阶之不可变性

    万次阅读 2020-12-20 11:58:21
    1. 不可变性的实现方式 2. 为什么需要不可变性或者说是不可变性的好处 3. 不可变性的不足以及改进方案
  • 问题由来Java编程中有的时候我们会在控制台输入长度可变的数组数据(分隔符一致),例如:1 2 3 4 5 6或者1,2,3,4,5,6,7然后对这串未知长度的数据进行处理,得到对应类型的数组。分析1.由于长度可变,所以能直接用...
  • Python中迭代对象是什么?

    万次阅读 多人点赞 2019-06-30 22:59:56
    Python中迭代对象(Iterable)并是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )方法或__getitem__( )方法访问。 __iter__方法的作用是让对象可以用for … in循环...
  • HashMap中的key可以是null,基本数据类型或引用数据类型。为了HashMap的正常使用,key一般是不可变对象,至少该对象中用于计算hash值的属性要不可,方可保证HashMap的正常使用。...
  • python中的迭代对象

    万次阅读 多人点赞 2017-08-03 22:58:28
    迭代对象 我们已经知道可以对list、tuple、str等类型的数据使⽤for...in...的循环语法从 其中依次拿到数据进⾏使⽤,我们把这样的过程称为遍历,也叫迭代。 但是,是否所有的数据类型都可以放到for..
  • 一般也建议用List去填充数据显示控件的数据源。 如果一定要用List对象去绑定数据源,那么首先设置DataGridView的DataSource属性为new List(),然后再将List集合重新赋值给DataSource属性。这样既解决同步更新...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,516,276
精华内容 1,006,510
关键字:

不可变数据对象