一、python中的变量与对象

首先在理解python的可变对象和不可变对象时,要理解python的赋值操作。在python中,一切事物皆是对象,变量是对象在内存中的存储和地址的抽象

对变量的理解

在Python中,类型是属于对象的,而不是变量, 变量和对象是分离的,对象是内存中储存数据的实体,变量则是指向对象的指针。

“=”(赋值号)是将右侧对象的内存地址赋值给左侧的变量。

当我们写下面语句时

a = "abc"

Python解释器其实顺序干了两件事情:

1 在内存中创建一个字符串“abc”;

2 在内存中创建一个名为“a”的变量,并将“a”指向字符串“abc”(将“abc”的地址保存到“a”中)。

这样我们就能通过操作“a”而改变内存中的“abc”。

二、什么是可变对象/不可变对象

不可变对象 该对象所指向的内存中的值不能被改变当改变一个变量的时候,由于改变量所指向的内存中的值不能被改变,因此会将原来的值复制一份后再改变,具体做法是重新开辟一块空间存放新的值,并将该变量指向这个空间。原来空间中的值如果没有变量指向它,会被当做垃圾回收。数值类型(int float), 字符串str, 元组tuple是不可变的数据类型

可变对象 该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。列表list, 字典dist, 集合set是可变的数据类型

举例说明

不可变对象的例子

>>> a = 'hello'

>>> id(a)

1921615688624

>>> a = 'world'

>>> id(a)

1921615689744

# 重新赋值之后,变量a的内存地址已经变了

# 'hello'是str类型,不可变,所以赋值操作重新创建了str对象 'world'对象,

# 然后将变量a指向了它

可变对象的例子

>>> lst = [1, 2, 3]

>>> id(lst)

1921615726216

>>> lst.append(4)

>>> id(lst)

1921615726216

# list重新赋值之后,变量lst的内存地址并未改变

# [1, 2, 3]是可变的,append操作只是改变了其value,变量lst指向没有变

三、python引用

python一般内部赋值变量的时候,都是传递一个引用变量,和C语言的传地址的概念差不多, 比如:

>>> a = [1,2,3] # 表示变量a保存了这个列表的地址

# python里可以用id()来查询下a在内存的地址是:1921615756616

>>> id(a)

1921615756616

>>> b = a

# 那b的内容是什么,地址又是什么呢?

# 用print 输出下b的内容也是[1,2,3]

# 然后我们查看下b的地址看下能否验证我们的结论

>>> b

[1, 2, 3]

# 果然b的地址也是:1921615756616

>>> id(b)

1921615756616

这样会带来一个问题,因为变量a,和变量b都是保存了同一个列表的地址。如果我改变a指向的列表的值的话,那b指向的列表的值也同时改变

>>> a[1] = 6

>>> a

[1, 6, 3]

>>> b

[1, 6, 3]

如果我们只想修改a列表里面的内容。而不想修改b的内容,那就要用到python的拷贝了

>>> a = [1,2,3]

>>> b = a[:]

>>> a[1] = 6

>>> a

[1, 6, 3]

>>> b

[1, 2, 3]

四、函数值传递

首先来看一个例子

def func_int(a):

a += 4

def func_list(lst):

lst[0] = 4

t = 0

func_int(t)

print t

# output: 0

t_list = [1, 2, 3]

func_list(t_list)

print t_list

# output: [4, 2, 3]

主要是因为可变对象和不可变对象的原因:对于可变对象,对象的操作不会重建对象,而对于不可变对象,每一次操作就重建新的对象。

在函数参数传递的时候,Python其实就是把参数里传入的变量对应的对象的引用依次赋值给对应的函数内部变量。参照上面的例子来说明更容易理解,func_int中的局部变量"a"其实是全部变量"t"所指向对象的另一个引用,由于整数对象是不可变的,所以当func_int对变量"a"进行修改的时候,实际上是将局部变量"a"指向到了整数对象"1"。所以很明显,func_list修改的是一个可变的对象,局部变量"a"和全局变量"t_list"指向的还是同一个对象。

五、深拷贝 & 浅拷贝

接下来的问题是:如果我们一定要复制一个可变对象的副本怎么办?简单的赋值已经证明是不可行的,所以Python提供了copy模块,专门用于复制可变对象。

copy中有两个方法:copy()和deepcopy(),前一个是浅拷贝,后一个是深拷贝。

浅拷贝仅仅复制了第一个传给它的对象,下面的不管了;而深拷贝则将所有能复制的对象都复制了。

>>> import copy

>>> a = [[1,2,3], [4,5,6]]

>>> b = a

>>> c = copy.copy(a)

>>> d = copy.deepcopy(a)

>>>

>>> a.append(15)

>>> a[1][2] = 10

>>> a

[[1, 2, 3], [4, 5, 10], 15]

>>> b

[[1, 2, 3], [4, 5, 10], 15]

>>> c

[[1, 2, 3], [4, 5, 10]]

>>> d

[[1, 2, 3], [4, 5, 6]]

六、作用域

在Python程序中创建、改变或查找变量名时,都是在一个保存变量名的地方进行中,那个地方我们称之为命名空间。作用域这个术语也称之为命名空间。

变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局,最后是内置。在默认情况下,变量名赋值会创建或者改变本地变量。全局声明将会给映射到模块文件内部的作用域的变量名赋值。Python 的变量名解析机制也称为 LEGB 法则,具体如下:

当在函数中使用未确定的变量名时,Python搜索4个作用域:

本地作用域(L)

上一层嵌套结构中 def 或 lambda 的本地作用域(E)

全局作用域(G)

内置作用域(B)。

按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错的。

python哪些是可变对象_Python中的可变对象和不可变对象相关推荐

  1. python中函数的可变参数_Python中函数的参数定义和可变参数

    转自:http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944416.html 刚学用Python的时候,特别是看一些库的源码时,经常会看到fun ...

  2. python中不可变对象_Python中的可变对象与不可变对象、浅拷贝与深拷贝

    Python中的对象分为可变与不可变,有必要了解一下,这会影响到python对象的赋值与拷贝.而拷贝也有深浅之别. 不可变对象 简单说就是某个对象存放在内存中,这块内存中的值是不能改变的,变量指向这块 ...

  3. python中元组的值可变吗_python中对象的可变与不可变

    在python中一切皆对象,对象是对数据的抽象. 所有对象有三个要素:类型.标识.值.类型决定对象可以支持哪些操作:标识指的是对象的内存地址,每个对象有唯一的地址,通过id内建函数可以求出地址:值从字 ...

  4. python中字典长度可变吗_python中列表长度可变吗

    python中列表长度可变吗?下面给大家介绍一下python中可变和不可变的类型: 可变.不可变 可变/不可变类型,指的是:内存id不变,type也不变的前提下,value是否是可变的. int()和 ...

  5. python中的对象_Python中的变量、对象

    由于没时间系统学习下Python 只能见一个问题探究一个问题了 一.初级 - 对象 关于Python中的数据类型,今天重新认识了下.[参考] 首先,Python中,对象才有类型, 变量是没有类型的,它 ...

  6. python列表长度可变吗_python中列表长度可变吗

    python中列表长度可变,可变类型指的是内存id不变,type也不变的前提下,value是否是可变的.列表和字典都是可变类型,对于可变对象,比如list,对list进行操作,list内部的内容是会变 ...

  7. python比较两个数的和_Python中的is和==比较两个对象的两种方法

    Python中的is和==比较两个对象的两种方法 在Python中有两种方式比较两个对象是否相等,分别是is和==,两者之间是不同的 ==比较的是值(如同java中的equals方法) is比较的是引 ...

  8. python一切皆对象_Python中一切皆为对象

    众所周知,面向对象语言的特点即为"万物皆为对象",其中以Java开发尤为突出.那么在python中,这个 一切 是怎么表现出来的呢? 一切皆为对象(函数和类也是对象) 在Pytho ...

  9. python中什么叫类、什么叫对象_python中的类面向对象的基本概念!

    一.概述 今天我们讲述Python中的类&面向对象的基本概念. 首先我们为什么要学习面向对象,我讲一个故事,应该就可以明白了.在古时候,官府衙门如果要颁布什么告示就会去找工匠将命令中的字都雕刻 ...

最新文章

  1. 在ASP.NET MVC3项目中,自定义404错误页面
  2. php简单的mysql类_超简单php mysql数据库查询类
  3. IUnknown接口QueryInterface函数介绍
  4. tomcat jdbc SlowQueryReport的实现解读
  5. haproxy安装配置及haproxy+keepalived简单配置
  6. 管理感悟:回字有几种写法的面试
  7. 如果Linux从未出现,我们的生活会变成怎样?
  8. WPF之HierarchicalDataTemplate
  9. 关于ESAPI无法打印debug级别日志
  10. matlab将数据集分成训练集和测试集,如何将数据分成训练集和测试集?
  11. 阿里云DataV数据展示的一些sql写法
  12. NOIP学习之综合应用:163.出书最多
  13. 【数字信号调制】基于matlab实现AM调制系统附GUI界面
  14. 微信公众平台开发教程
  15. python调用报表制作工具_Python如何使用xlwt制作一个表格
  16. JDK各个版本安装以及配置,超详细
  17. python数据清洗面试题_利用python进行数据清洗
  18. 操作系统---文件管理
  19. onshow 和 onload 的区别
  20. asp.net 母版页使用详解

热门文章

  1. 可用的双目标定代码(先单目标定再双目标定)
  2. 一篇文档掌握Jdk8中Javascript引擎Nashorn的使用方法
  3. Chrome Devtool 调试 Javascript
  4. 品牌活动软文怎么写?
  5. Netty异步非阻塞事件驱动及组件原理详解
  6. 2023年乘坐火车高铁成人儿童旅客列车临时身份证明手机在线如何办理乘车临时身份证明?
  7. 2000-2018年286个地级市PM2.5数据
  8. 计算机二级一做题就不会,备考计算机二级office考试,如何提高做题速度?
  9. 绝对定位position:absolute;实现居中对齐
  10. 视频手术刀 video bistoury(三)--Opengl 基石