Python中只有一个赋值模型
一、缺少类型声明语句的情况
在Python中,类型是在运行过程中自动决定的,而不是通过代码声明。这意味着没有必要事声明变量。只要记住,这个概念实质上对变量,对象和它们之间的关系都适用。那么这个概念也容易理解并掌握。
1、变量,对象和引用
变量创建:一个变量,当代码第一次给它赋值时它就被创建了。之后的赋值将会改变已创建的变量名的值。Python在代码运行之前先检测变量名,可以当成是最初的赋值创建变量。
变量类型:变量永远不会有任何的它关联的类型信息或约束。类型的概念是存在于对象中而不是变量中。变量原本是通用的。它只是在一个特定的时间点,简单地引用了一个特定的对像而已。
变量的使用:当变量出现在表达式中时,它会马上被当前引用的对像所代替,无论这个对象是什么类型。
此外,所有的变量都必须在其使用前明确地赋值。使用未赋值的变量会产生错误。
>>>a=3
在概念上说,Python将执行三个不同的步骤去完成这个请求。
1)、创建一个对象来代表值3
2)、创建一个变量a,如果它还没有创建的话
3)、将变量与新的对象3连接
在python中从变量到对象的连接称作引用。引用是一种关系,以内存中的指针形式实现。
*变量 是一个系统表的元素,拥有指向对象的连接空间。
*对象 是被分配的一块内存,有足够的空间去表现它们所代表的值。
*引用 是自动形成的从变量到对象的指针。
每一个对象都用两个标准的头部信息:一个类型标志符去标识这个对象的类型,以及一个引用的计数器,用来决定是不是可以回收这个对象。
2、类型属于对象,而不是变量
Python中的类型是与对象相关联的,而不是和变量关联。
变量没有类型,变量指向对象。对象有类型,知道自己的类型,每个对象都包含了一个头部信息,其中标记了这个对象的类型。
3、对象的垃圾收集
对象生命结束时发生了什么变化?
每当一个变量名被赋与了一个新的对象,之前的那个对象占用的空间就会被收回(如果它没有被其他变量名和对象所引用).这种自动回收对象空间的技术称作垃圾收集。
在内部,Python是通过保持用每个对象中的计数器记录引用指到这个对象上的次数来完成这一功能。一旦(并精确在同一时间)这个计数器被设置为零,这个对象的内存空间就会自动收回。垃圾收集最直接的,可感受到的好处就是这意味着可以在脚本中任意使用对象而不需要考虑释放内存空间。
>>> x=42
>>> id(x)
674748828
>>> x="diege"
>>> id(x)   
676367648

二、共享引用
上面所讲都是单个变量被赋值引用了多个对象的情况。现在,在交互模式下,引入另一个变量,并看一下变量名和对象的变化。
>>> a=10
>>> b=a
>>> id(a)
674749212
>>> id(b)
674749212
第二行会使用python创建变量b。使用的是变量a,并且它在这里没有被赋值,所以它被替换成其应用的对象10,从而b也成为这个对象的一个引用。实际效果就是变量a和b都引用相同的对象(也就是说指向了相同的内存空间。在Python中称作是共享引用--多个变量名应用了同一个对象。)
>>> a=10
>>> b=a 
>>> a='diege'
>>> id(a)
676367648
>>> id(b)
674749212
变量a改变了,但是不影响变量b.这完全可以说明变量b是指向对象10内存空间的。
在ptyhon中,变量总是一个指向对象的指针,而不是可以改变的内存区域的标签。给一变量赋一个新的值,并不是替换了原始的对象,而是让这个变量去引用完全不同的一个对象。实际的效果就是对一个变量赋值,仅仅会影响那个被赋值的变量。
1、共享引用和在原处修改
有一些对象和类型确实会在实地改变对象。例如,在一个列表中对一个偏移进行赋值确实会改变这个列表对象,而不是生成一个新的列表对象。
>>> T1=[11,12,13]
>>> T2=T1
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T1=22
>>> T1
22
>>> T2
[11, 12, 13]
这个和先前一样T1改变了T2没有改变,T2改变也不影响T1
>>> T1=[11,12,13]
>>> T2=T1
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T2[1]=33    
>>> T1
[33, 12, 13]
>>> T2
[33, 12, 13]
发现T2改变了,T1也跟这改变了.
同样T1改变了,T2也改变了
>>> T1[1]=99 
>>> T2
[33, 99, 13]
>>> T1
[33, 99, 13]
这里T1没有改变,改变了T1所引用对象的一个元素。这类修改会覆盖列表对象中的某部分。因为这个列表对象是与其他对象共享的(被其他对象引用),那么一个像这样在原处的改变不仅仅会对T1有影响。必须意识到当做了这样的修改,它会影响程序的其他部分。

如果不想要这样的现象发生,需要Python拷贝对象,而不是创建引用。方法包括内置列表函数以及标准库的copy模块,最常用的办法就是从头到尾的分片T1[:]
>>> T1=[11,12,13]
>>> T2=T1[:]
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T1[0]=99
>>> T1
[99, 12, 13]
>>> T2
[11, 12, 13]
>>> id(T1)
676366604
>>> id(T2)
675542060
T1和T2指向不同的对象,所以不会相互影响。
注意:这种分片技术不会引用在其他的可变的核心类型上(字典,因为它们不是序列),对字典应该使用D.copy()方法.而且,注意标准库中的copy模块有一个通用的拷贝任意对象的调用,也有一个拷贝嵌套对象的结构的调用.
>>> X={'name':'diege','age':28} 
>>> import copy
>>> Y=copy.copy(X)
>>> X
{'age': 28, 'name': 'diege'}
>>> Y
{'age': 28, 'name': 'diege'}
>>> id(X)
676370468
>>> id(Y)
676414436
>>> X={'name':{'FirstName':'diege','LastName':'wangkaijin'},'age':28}   
>>> X
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
>>> Y=copy.copy(X)
>>> Y
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
>>> Z=copy.deepcopy(X)
>>> Z
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
2、共享引用和相等
>>> x=33
>>> x='diege'
因为Python缓存并复用了小的整数和小的字符串,就像前文提到的那样,这里对象33也许不像前期所说的被收回,相反,它将可能仍保持在一个系统表中,等待下一次你的代码生成另一个33来利用。尽快如此,大多数种类的对象都会在不再引用时马上回收。对于那些不会被回收的,缓冲机制与代码并没有什么关系。
判断是否相等
>>> L=[1,2,3]
>>> M=L
>>> L==M
True
>>> L is M
True
==检查对象是否有相同的值。 is操作符,检查对象的同一性。如果两个变量名精准地指向同一个对象,它会返回True。所以这是一种更严格的相等测试。
实际上,is只是比较现实引用的指针。所以如果必要的话是代码中检测共享引用的一种方法。如果变量名引用值相等。但是为不同的对象,它的返回值将是False.
>>> L=[1,2,3]
>>> M=[1,2,3]
>>> L==M
True
>>> L is M
False
>>> id(L)
676367788
>>> id(M)
676367724
通过id()函数可以看到两个变量指向不同的对象。
>>> X=33
>>> Y=33
>>> X==Y
True
>>> X is Y
True
>>> id(X)
674748936
>>> id(Y)
674748936
这个is测试返回True因为小的整数和字符串被缓存被复用了。
如果想更进一步了解,可以向Python查询一个对象应用的次数:在sys模块中的getrefcount函数返回对象应用的次数。
>>> import sys
>>> sys.getrefcount(33)
13
>>> sys.getrefcount(1)
427
>>> sys.getrefcount(00)
296
>>> sys.getrefcount(99)
6

转载于:https://blog.51cto.com/ipseek/786518

Python学习笔记整理(三)Python中的动态类型简介相关推荐

  1. Python 学习笔记 第三篇 Python实现网易云评论网页爬虫+词云展示 (Pycharm+Mysql)

    初始条件,具体可见我的其他文章. 1.安装Python.Python 学习笔记 第一篇 Python的安装与配置 2.安装Pycharm,并导入第三方包.Python 学习笔记 第二篇 Python ...

  2. python学习笔记26(python中__name__的使用)

    python学习笔记26(python中__name__的使用) 在python中,每个py文件都是一个模块,也都是一个可执行文件,即包含main方法.因此,对每个py文件,可以单独运行,也可以imp ...

  3. Python学习笔记:使用Python操作数据库

    Python学习笔记:使用Python操作数据库 一.数据库编程接口 为了对数据库进行统一的操作,大多数语言都提供了简单的.标准化的数据库接口(API).在Python Database API 2. ...

  4. Python学习笔记:用Python获取数据(本地数据与网络数据)

    Python学习笔记:用Python获取数据(本地数据与网络数据) 一.用Python获取本地数据 读写文件(三种基本模式:r, w, a) 1.写文件 2.读文件

  5. Java快速入门学习笔记2 | Java语言中的基本类型

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  6. python学习笔记1之-python简介及其环境安装

    python学习笔记之-python简介及其环境安装 最近几年python之火不用多说,最近开始利用时间自学python,在学习的过程中,按照自己的思路和理解记录下学习的过程,并分享出来,如果正好你也 ...

  7. Python学习笔记 ---第三章

    函数 函数是代码的一种抽象 函数 说明 abs 绝对值 max 最大值 hex 转换为16进制 强制数据类型转换 int('123') 123 int(12.35) 12 srt(100) '100' ...

  8. 流畅的python学习笔记(三):数据结构(3:文本和字节序列)

    文本和字节序列 大纲 1. 字符问题 2. 字节概要 2.1 结构体和内存视图 3. 基本的编解码器 4. 了解编解码问题 4.1 处理UnicodeEncodeError 4.2 处理Unicode ...

  9. 流畅的python学习笔记(三):数据结构(1)

    文章目录 概述 序列 列表推导和生成器表达式 列表推导和可读性 列表推导同filter和map的比较 笛卡尔积 生成器表达式 元组不仅仅是不可变的列表 把元组用作记录 元组拆包 嵌套元组拆包 具名元组 ...

最新文章

  1. 串口流控--软件流控与硬件流控
  2. 这篇文章让我步入了无线时代,感激原创。
  3. HTTP简介,http是一个属于应用层的面向对象的协议
  4. 优化order by语句
  5. Linux 系统下载和安装 rarlinux
  6. c语言程序设计小学生测验,c语言程序设计(1) 小学生计算机辅助教学系统
  7. 【Android工具】Yandex!懂你的超级好用手机浏览器,可以安装PCchrome插件的手机浏览器!...
  8. 使用树莓派实现微信远程监控
  9. macbook air从win10回到macOS Sierra
  10. 为什么你的需求估算老是翻车?看看这个故事就明白了......
  11. 推荐系统论文11月组队学习
  12. HBASE region简介
  13. 手机和电脑如何连接无线投影仪
  14. 计算机编程 计算存款利息,作业报告12 定期存款利息计算器
  15. python识别手写数字字体_基于tensorflow框架对手写字体MNIST数据集的识别
  16. bi工具有哪些,该怎么选择呢?
  17. UserControl关闭事件
  18. 研究生应当常去的网站
  19. pycharm汉化之后切换回英文
  20. 神经网络的前向和反向传播

热门文章

  1. java中文乱码解决之道(五)—–java是如何编码解码的
  2. oracle数据库中VARCHAR2(50 CHAR) 和VARCHAR2(50) 有啥区别?
  3. 推翻自己和过往,重学自定义View
  4. Acitivty生命周期
  5. 一款不错的网站压力测试工具webbench
  6. 英文版opensuse 12.2安装中文输入法ibus
  7. CentOS 6.5 部署WordPress
  8. html-盒子模型及pading和margin相关
  9. 解决vue单页路由跳转后scrollTop的问题
  10. 62、滑动窗口的最大值