今天浏览博客的时候看到这么一句话: python中变量名和对象是分离的;最开始的时候是看到这句话的时候没有反应过来。决定具体搞清楚一下python中变量与对象之间的细节。(其实我感觉应该说 引用和对象分离 更为贴切)

从最开始的变量开始思考:

在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可 (这个和C语言等静态类型语言不同,和python为动态类型有关)。

举第一个栗子:

a = 1

这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1;这边形象比喻一下:这个过程就相当于“放风筝”,变量a就是你手里面的“线”,python就跟那根“线”一样,通过引用来接触和拴住天空中的风筝——对象。

你可以通过python的内置函数 id() 来查看对象的身份(identity),这个所谓的身份其实就是 对象 的内存地址:

注:

python一切皆对象的理念,所以函数也是一个对象,因此可以使用 id() 函数的__doc__方法来查看这个函数的具体描述:

>>> id.__doc__

"id(object) -> integer\n\nReturn the identity of an object. This is guaranteed to be unique among\nsimultaneously existing objects.       (Hint: it's the object's memory address.)"

第二个栗子:

a = 2

a = 'banana'

利用上面第一个栗子用到的 id()函数:

>>> a = 1

>>> id(a)

24834392

>>> a = 'banana'

>>> id(a)

139990659655312

第一个语句中, 2是储存在内存中的一个整数对象,通过赋值 引用a 指向了 对象 1

第二个语句中,内存中建立了一个字符串对象‘banana’,通过赋值 将 引用a 指向了 ‘banana’,同时,对象1不在有引用指向它,它会被python的内存处理机制给当我垃圾回收,释放内存。

第三个栗子:

a = 3

b = 3

通过函数查看 变量a 和 变量b的引用情况:

>>> a = 3

>>> b = 3

>>> id(a)

10289448

>>> id(b)

10289448

在这里可以看到 这俩个引用 指向了同一个 对象,这是为什么呢? 这个跟python的内存机制有关系,因为对于语言来说,频繁的进行对象的销毁和建立,特别浪费性能。所以在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。

第四个栗子:

1. a = 4

2. b = a(这里就是让引用b指向引用a指向的那个对象)

3. a = a + 2

通过函数查看引用情况:

当执行到第2步的时候,查看一下 a 和 b 的引用:

>>> a = 4

>>> b = a

>>> id(a)

36151568

>>> id(b)

36151568

可以看到 a 和 b 都指向了 整数对象 4

接下来指向第3步:

>>> a = a+2

>>> id(a)

36151520

>>> id(b)

36151568

可以看到 a 的引用改变了,但是 b 的引用未发生改变;a,b指向不同的对象; 第3句对 a 进行了重新赋值,让它指向了新的 对象6;即使是多个引用指向同一个对象,如果一个引用值发生变化,那么实际上是让这个引用指向一个新的引用,并不影响其他的引用的指向。从效果上看,就是各个引用各自独立,互不影响。

第五个栗子(这个栗子会涉及到 python中的 可变数据类型 和 不可变数据类型):

开始这个栗子之前,请记得注意到 第四个栗子的不同之处。

1. L1 = [1, 2, 3]

2. L2 = L1

3. L1[0] = 10

通过函数查看引用情况:

当执行第1步 和 第二步 的时候,查看一下 L1 和 L2 的引用情况:

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

>>> L2 = L1

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

此时 L1 和 L2 的引用相同,都是指向 [1,2,3]这个列表对象。

接下来,继续执行第3步:

>>> L1[0] = 10

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

>>> L2

[10, 2, 3]

同样的跟第四个栗子那样,修改了其中一个对象的值,但是可以发现 结果 并不与 第四个栗子那样, 在本次实验中,L1 和 L2 的引用没有发生任何变化,但是 列表对象[1,2,3] 的值 变成了 [10,2,3](列表对象改变了)

在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。

原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)

列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。

而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。

我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

is关键字:

当然,我们也可以要想知道是否指向同一个对象,我们可以使用 python的 is 关键词,is用于判断两个引用所指的对象是否相同。

就像上述第四个栗子 当进行到 第1步 和 第2步 的时候:

>>> a = 4 ……id(a) = 36151568

>>> b =a ……id(b) = 36151568

>>> a is b

True

当进行到第3步的时候:

>>> a = a + 2 ……id(a) = 36151520

>>> a is b ……id(b) = 36151568

False

突然想到,对于python 的 深拷贝 和 浅拷贝 的理解,也是可以根据这个进行验证,可以通过第五个栗子进行辅助理解。

python中的引用怎么理解_python 引用和对象理解相关推荐

  1. python中object是什么类型_python中类与对象之继承

    面对对象的三大特性之继承 1.什么是继承? 在程序中,继承指的是class与class之间的关系 继承是一种关系,必须存在两个class才能产生这种关系:被继承的class称为父类,继承的class称 ...

  2. python中copy函数怎么用_python怎样copy对象

    copy.copy 浅拷贝 仅仅拷贝父对象,不会拷贝对象的内部的子对象. copy.deepcopy 深拷贝 拷贝对象及其子对象 例如import copy a = [1, 2, 3, 4, ['a' ...

  3. [转载] python中for语句用法_详解Python中for循环的使用_python

    参考链接: 在Python中将else条件语句与for循环一起使用 这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 &q ...

  4. python中for语句用法_详解Python中for循环的使用_python

    这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 "探索 Python,第 5 部分:用 Python 编程&q ...

  5. python中的作用域以及优先级_Python中的作用域规则详解

    Python是静态作用域语言,尽管它自身是一个动态语言.也就是说,在Python中变量的作用域是由它在源代码中的位置决定的,这与C有些相似,但是Python与C在作用域方面的差异还是非常明显的. 接下 ...

  6. python中异或怎么算_python 异或运算的前提_异或运算公式

    Python基础(10)–数字-Python-第七城市 609x288 - 73KB - JPEG Python基础(10)--数字_资讯_突袭网 609x288 - 33KB - JPEG pyth ...

  7. python中print是什么意思_python中print什么意思

    python中print什么意思,多个,是一个,对象,语法,默认值 python中print什么意思 易采站长站,站长之家为您整理了python中print什么意思的相关内容. python中prin ...

  8. python中标识符的命名规则_Python——标识符的命名规则

    01 Python语言的特点 python的语言特点有很多,我们这里只讲一点,python是一门面向对象的语言,即一切皆对象(Linux中有一句是:一切皆文件),括号内的只是打个比方,不懂也没事,就是 ...

  9. python中if语句的实例_Python基础入门-IF语句

    今天给大家分享一下Python中的IF语句的使用场景以及注意事项.主要内容如下: 1.python中的真假 2.Python操作符 3.if语句实例和嵌套实例 4.if语句中的if嵌套实例 5.and ...

  10. python中values是什么意思_Python values()与itervalues()的用法详解

    dict 对象有一个 values() 方法,这个方法把dict转换成一个包含所有value的list,这样,我们迭代的就是 dict的每一个 value: d = { 'Adam': 95, 'Li ...

最新文章

  1. Python Numpy介绍
  2. 将用户名保存至cookie中
  3. java gc回收区域_java内存区域以及GC回收
  4. 孩子数学总是考不好?做好这五点,下次成绩一定好
  5. php 5.6 引用传递,升级到5.6.x后如何在php中修复引用传递
  6. Mr.J-- jQuery学习笔记(二十四)--剖析jQuery源码--extend
  7. Kotlin — Springboot 与 Kotlin构建Web应用程序
  8. Python IO模型
  9. Android性能专项测试之Systrace工具
  10. Vue + Element-UI —— 项目实战(一)
  11. Tracup|使用项目管理独一无二的六大好处
  12. vbs查看系统开关机时间
  13. 基于pyqt5的登录界面及人脸识别功能界面相互跳转的设计(1)
  14. 自动计数报警器c语言,基于51单片机的光电式计数报警器
  15. [蓝桥杯]校内培训交流会总结
  16. 抖音快手短视频批量去水印采集软件v1.8使用文档
  17. RPGMaker MV 插件基础04:插件指令与脚本
  18. 安全加固——Windows系统安全加固
  19. Linux-Ubuntu16-04-的安装与美化
  20. 为什么你投了那么多份简历都没有回应?手把手教你写简历

热门文章

  1. ArrayList与String[]
  2. Android 统一View样式,textview样式
  3. linux命令行sip电话,基于Linux和MiniGUI的SIP电话终端设计
  4. 开启Mysql远程登录账号
  5. dbeaver 连接hbase 数据库
  6. babel 用法及其 .babelrc 的配置详解,想做前端架构,拒绝一知半解...
  7. git保留两个repo的commit并进行合并
  8. 算法基础——列表查找
  9. Swift 将日期转化为字符串,显示上午还是下午
  10. 学习曾国藩,学做人做事学技术