python可变类型和不可变类型

原文地址:http://www.cnblogs.com/huamingao/p/5809936.html

可变类型 Vs 不可变类型

可变类型(mutable):列表,字典

不可变类型(unmutable):数字,字符串,元组

这里的可变不可变,是指内存中的那块内容(value)是否可以被改变

代码:

name1=‘wupeiqi‘
name2=name1
print("name1:%s\nname2:%s" %(name1,name2))
name1=‘alex‘
print("I have assigned new value to name1.Let‘s see what happens to name2!")
print("name1:%s\nname2:%s" %(name1,name2))

执行结果:

name1:wupeiqi
name2:wupeiqi
I have renamed name1 to new_name.Let‘s see what happens!
name1:alex
name2:wupeiqi

疑问:为什么name2的值没有和name1一起变为alex?下面开始解答,先看图,后解释。

以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

变量的赋值

#!/usr/bin/env python
# -*- coding: utf-8 -*-

name1 = "wupeiqi"
name2 = "alex"

#!/usr/bin/env python
# -*- coding: utf-8 -*-

name1 = "wupeiqi"
name2 = name1     # 使name2和name1指向同一个对象 赋值,只是创建一个变量,该变量指向原来内存地址,

以上引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

1.引用计数的增减

当对象wupeiqi(图中蓝色的内存区块wupeiqi)被初次创建并(将其引用)赋值给变量name1时,对象wupeiqi的引用计数被设置为1。

当对象alex(图中蓝色的内存区块alex)被初次创建并(将其引用)赋值给变量name2时,对象alex的引用计数被设置为1。

当变量name1赋值给变量name2(name2=name1),实际是把对象wupeiqi赋值给name2,因此对象wupeiqi的引用计数自动加1,而对象alex的引用计数自动减1,即减为0,触发垃圾回收机制。

2. 可变类型 Vs 不可变类型

可变类型(mutable):列表,字典

不可变类型(unmutable):数字,字符串,元组

这里的可变不可变,是指内存中的那块内容(value)是否可以被改变。如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域#不可变#)。如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

可以使用内建函数id()来确认对象的身份在两次赋值前后是否发生了变化。示例可参看http://blog.chinaunix.net/uid-26249349-id-3080279.html

*不可变类型有什么好处?如果数据是不可变类型,当我们把数据传给一个不了解的API时,可以确保我们的数据不会被修改。如果我们要操作一个从函数返回的元组,可以通过内建函数list()把它转换成一个列表。(当被问到列表和元组的区别时,可以说这一点!)

3. 深拷贝 Vs 浅拷贝

copy.copy() 浅拷贝

copy.deepcopy() 深拷贝

浅拷贝是新创建了一个跟原对象一样的类型,但是其内容是对原对象元素的引用。这个拷贝的对象本身是新的,但内容不是。拷贝序列类型对象(列表\元组)时,默认是浅拷贝。

以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

赋值,只是创建一个变量,该变量指向原来内存地址,如下例:

n4 = n3 = n2 = n1 = "123/‘Wu‘"

关于赋值,再看一个字典的例子:

n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1

浅拷贝,在内存中只额外创建第一层数据,如下图

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n3 = copy.copy(n1)

深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化),如下图:

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n4 = copy.deepcopy(n1)

原文地址:https://www.cnblogs.com/hmw112626/p/9466816.html

时间: 2024-10-04 06:55:25

python可变类型和不可变类型的相关文章

Python的可变类型与不可变类型

Python的每个对象都分为可变和不可变,主要的核心类型中,数字.字符串.元组是不可变的,列表.字典是可变的. 对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其他变量引用原有对象的话(即引用计数为0),原有对象就会被回收). 不可变类型以int类型为例:实际上 i += 1 并不是真的在原有的int对象上+1,而是重新创建一个value为6的int对象,i引用自这个新的对象. >>> i = 5 >>> i

Python可变类型 Vs 不可变类型

可变类型 Vs 不可变类型(这里的可变不可变,是指内存中的那块内容(value)是否可以被改变.) 可变类型(mutable):列表,字典 不可变类型(unmutable):数字,字符串,元组 如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域#不可变#).不允许变量的值发生变化,如果改变了变量的值,相当于新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量来引用这个对象,当引用计算变为0的时候,就启用垃圾回收机制,原

python可变类型与不可变类型

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

Python 可变类型和不可变类型,以及其引用

基本数据类型的引用        在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址.访问这块内存需要用到变量名,变量名实际存储的是变量的地址在内存中的地址,但是使用print()函数得到的确实这块内存中实际的地址.这个就当成规定就好,没必要纠结. 获得变量在内存中的地址,可以使用id()函数. 常规使用        变量之间的赋值其实是把一个变量的内存地址传递给另一个变量,这样两个变量便都指向内存中的同一块空间,因此这两个变量的之

linux 可变类型与不可变类型

Python的每个对象都分为可变和不可变,主要的核心类型中,数字.字符串.元组是不可变的,列表.字典是可变的. 可变类型和不可变类型有些地方区别很大,注意区分. 对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其他变量引用原有对象的话(即引用计数为0),原有对象就会被回收). 不可变类型 以int类型为例:实际上 i += 1 并不是真的在原有的int对象上+1,而是重新创建一个value为6的int对象,i引用自这个新的对象. 可以

可变类型与不可变类型的作用和意义

Python中的变量分为可变类型和不可变类型 两种. 可变类型: 数字.字符串.元组.可变集合. 不可变类型: 列表.字典.不可变集合. 这里的可变不可变,是指内存中的那块内容(value)是否可以被改变 根据存储的内容是否可变划分为可变类型与不可变类型.如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请 一块区域(因为老区域是不可变).如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连 续申请(+/-)即可,也就是它的address空间地址会保持不变,

03 可变类型与不可变类型

'''''' ''' 不可变类型:变量的值修改后内存地址不一样 数字类型 int float 字符串类型 str 元组类型 tuple 可变类型: 列表类型 list 字典类型 dict ''' #int number = 100 print(id(number)) #1717008960 number = 111 print(id(number)) #1717009312 #float sal = 1.0 print(id(sal)) #2115946484240 sal = 2.0 prin

关于java可变(协变)返回类型的解说之一------------基类与派生类

在java代码中,人们惯性的认为一个方法中只能返回一种返回值或者无返回.博主在做开发过程中碰到了这样一种情况,安卓客户端请求数据,后台可能返回两种结果(1)访问令牌失效,无数据返回.(2)正常获取数据. 这样的情况下需要根据访问令牌标识来判断是否有数据返回.当无效时返回用户重新登录提示,正常时则返回数据.显然,返回的结果有两种,那么一个方法里面只能返回一种类型的禁锢使得开发起来略显笨拙.使得开发起来相当难受. 思考良久,又结合C++协变返回类型的启发.摘抄原文中的一句话:在C++中,只要原来的返

python学习笔记17(动态类型)

动态类型 在我们接触的对象中,有一类特殊的对象,是用于存储数据的,常见的该类对象包括各种数字,字符串,表,词典.在C语言中,我们称这样一些数据结构为变量,而在Python中,这些是对象. 对象是储存在内存中的实体.但我们并不能直接接触到该对象.我们在程序中写的对象名,只是指向这一对象的引用(reference). 引用和对象分离,是动态类型的核心.引用可以随时指向一个新的对象: a = 3 a = 'python' 第一个语句中,3是储存在内存中的一个整数对象,通过赋值,引用a指向对象3. 第二