Python基础系列讲解—动态类型语言的特点
前言
在C语言中变量所分配到的地址是内存空间中一个固定的位置,当我们改变变量值时, 对应内存空间中的值也相应改变。在Python中变量存储的机制是完全不一样的,当给一个变量赋值时首先解释器会给这个值分配内存空间,然后将变量指向这个值的地址,那么当我们改变变量值的时候解释器又会给新的值分配另一个内存空间,再将变量指向这个新值的地址,所以和C语言相比,在Python中改变的是变量所指向的地址,而内存空间中的值是固定不变的。
例程介绍
我们可以通过id方法查看变量的内存地址的方式来进行验证。以下先以Python的int类型为例,可以看到执行 i += 1 后,变量i的内存地址会发生变化,事实上 i += 1 并不是在原有变量i的地址上加1,而是重新创建一个值为6的int对象,变量i则引用了这个新的对象,因此当变量i和变量j的值相同时会指向同个内存地址 。同样以Python的float 类型为例也验证了这个变量存储管理的机制。
#int
i = 5
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
i += 1
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
j = 5
print "j ---> ",j
print "id(j) ---> ",hex(id(j))
______________________
i ---> 5
id(i) ---> 0xa26f880
i ---> 6
id(i) ---> 0xa26f874
j ---> 5
id(j) ---> 0xa26f880
#float
i = 1.5
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
i += 1
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
j = 1.5
print "j ---> ",j
print "id(j) ---> ",hex(id(j))
______________________
i ---> 1.5
id(i) ---> 0x9e86c8c
i ---> 2.5
id(i) ---> 0x9e86cac
j ---> 1.5
id(j) ---> 0x9e86c8c
接下来以Python的list类型为例,可以看到list变量i在append之后,仍然指向同一个内存地址,而j、k的值虽然相同,但是指向的内存地址却不同。我们通过j = k 的赋值语句可以让j、k指向同一个内存地址,对j、k任意一个list变量进行修改,都会影响另外一个list变量的值。比如j变量append(4)时,同时对k变量也产生影响,查看j、k的内存地址,发现它们仍然指向了同个内存地址。
#list
i = [1, 2, 3]
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
i.append(4)
print "i ---> ",i
print "id(i) ---> ",hex(id(i))
j = [1.5, 2.5, 3.5]
print "j ---> ",j
print "id(j) ---> ",hex(id(j))
k = [1.5, 2.5, 3.5]
print "k ---> ",j
print "id(k) ---> ",hex(id(k))
j = k
print "j ---> ",j
print "id(j) ---> ",hex(id(j))
print "k ---> ",j
print "id(k) ---> ",hex(id(k))
j.append(4)
print "j ---> ",j
print "id(j) ---> ",hex(id(j))
print "k ---> ",j
print "id(k) ---> ",hex(id(k))
______________________
i ---> [1, 2, 3]
id(i) ---> 0xb73fa1acL
i ---> [1, 2, 3, 4]
id(i) ---> 0xb73fa1acL
j ---> [1.5, 2.5, 3.5]
id(j) ---> 0xb6fed06cL
k ---> [1.5, 2.5, 3.5]
id(k) ---> 0xb6fed04cL
j ---> [1.5, 2.5, 3.5]
id(j) ---> 0xb6fed04cL
k ---> [1.5, 2.5, 3.5]
id(k) ---> 0xb6fed04cL
j ---> [1.5, 2.5, 3.5, 4]
id(j) ---> 0xb6fed04cL
k ---> [1.5, 2.5, 3.5, 4]
id(k) ---> 0xb6fed04cL
刚才讲到Python的int类型的两个变量值相同时,Python解释器并不会分别为两个变量申请内存,而是优化的将他们指向同个内存地址。但这里有个例外的情况,当变量s1和s2 存储20个char时,Python仍然将两个变量引用指向了相同内存地址,但当存储为21个char时,Python为s2开辟了新的内存。厦门叉车多少钱
s1 = 'a' * 20
s2 = 'a' * 20
print hex(id(s1)), hex(id(s2))
0xb7075320L 0xb7075320L
s1 = 'a' * 21
s2 = 'a' * 21
print hex(id(s1)), hex(id(s2))
0xb70752f0L 0xb7075350L
总结
根据以上的这些例子,我们可以知道Python中的对象分为可变类型和不可变类型,列表、字典是可变类型,而整数、浮点、短字符串、元组等是不可变类型。可变类型的变量赋值与我们了解的C语言机制相同,而不可变类型的变量赋值时,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象,当然如果没有其他变量引用原有对象时,原有对象就会被回收。这也是Python作为动态类型语言的特点,即变量不需要预先声明类型,当变量在赋值时解释器会根据值的类型创建对应的内存空间进行存储,并将变量指向这个地址空间即可,比如运行a=1时,解释器将变量指向整形值1的地址,当运行a=0.1时,解释器将变量指向浮点值0.1的地址。
说明:此处的例程测试环境为Ubuntu 16.04 LTS 32 位,不同的环境下测试结果可能会由于解释器的优化不同而有所不同。比如有网友发现解释器为两个相同浮点类型值的变量分配了不同的内存空间。
Python基础系列讲解—动态类型语言的特点的更多相关文章
- Python基础系列讲解——继承派生和组合的概念剖析
Python作为一门面向对象的语言,它的面向对象体系中主要存在这么两种关系,一个是“类”和“实例”的关系,另一个是“父类”和“子类”的关系. 所谓“类”是从一堆对象中以抽象的方式把相同的特征归类得到的 ...
- Python基础系列讲解——try_except异常处理机制
在Python编程中不可避免的会出现错误,在调试阶段出现语法之类的错误时,Pycharm会在Debug窗口提示错误,但是程序在运行时由于内部隐含的问题而引起错误,会导致程序终止执行.比如以下例程中,使 ...
- Python基础系列讲解——random模块随机数的生成
随机数参与的应用场景大家一定不会陌生,比如密码加盐时会在原密码上关联一串随机数,蒙特卡洛算法会通过随机数采样等等.Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入ran ...
- Python基础系列讲解——TCP协议的socket编程
前言 我们知道TCP协议(Transmission Control Protocol, 传输控制协议)是一种面向连接的传输层通信协议,它能提供高可靠性通信,像HTTP/HTTPS等网络服务都采用TCP ...
- Python基础系列讲解-自动控制windows桌面
原链接:https://zhuanlan.zhihu.com/p/73001806 在使用PC时与PC交互的主要途径是看屏幕显示.听声音,点击鼠标和敲键盘等等.在自动化办公的趋势下,繁琐的工作可以让程 ...
- Python基础系列讲解——时间模块详解大全之time模块
Python中提供处理时间日期相关的内置模块有time.datetime和calendar. time模块中大多数函数调用了所在平台C library 的同名函数,因此更依赖于操作系统层面,所以tim ...
- Python 语言特性:编译+解释、动态类型语言、动态语言
1. 解释性语言和编译性语言 1.1 定义 1.2 Python 属于编译型还是解释型? 1.3 收获 2. 动态类型语言 2.1 定义 2.2 比较 2. 动态语言(动态编程语言) 3.1 定义 3 ...
- python基础系列教程——Python3.x标准模块库目录
python基础系列教程——Python3.x标准模块库目录 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata ...
- 【转】解析JDK 7的动态类型语言支持
http://www.infoq.com/cn/articles/jdk-dynamically-typed-language Java虚拟机的字节码指令集的数量自从Sun公司的第一款Java虚拟机问 ...
随机推荐
- php官网下载的chm手册,源码字号太小的问题解决
首先,到官方网站上下载chm格式的文档,地址如下: http://php.net/downloads.php 如图,点击荧光笔标出链接 然后就可以看到各种语言版本的文档手册,可以选择中文版,并带有笔记 ...
- java基础四 基本语法
java基本语法: 1:java严格区分大小写,好比main和Main是完全不同的概念. 2:一个java的源文件中可以定义多个类,但是其中最多只能一个类被定义成public类,若源文件中包括publ ...
- gulp插件(8) - gulp-sourcemaps(生成sourcemap)
功能描述生成sourcemap文件(什么是sourcemap?请参考,简单讲就是文件压缩后不利于查看与调试,但是有了sourcemap,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码) 插 ...
- P2758 编辑距离
题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1.删除一个字符: 2.插入一个字符: 3.将一个字符改为另一个字符: !皆为小写字 ...
- keepalived + nginx(负载均衡反向代理HTTP,https) + tomcat(HTTP,https)
基本架构: nginx(192.168.116.198) client --->keepalived(116.200) ------> tomcat (192.16 ...
- mysql命令框中向表中插入中文字符,在可视化工具MySQL Workbeach或phpMyAdmin中不显示或显示乱码的问题解决
一.问题导出 在刚刚开始学习MySQL数据库应用与开发这门课程的时候,老师建议我们使用可视化工具MySQL Workbeach进行数据库的相关管理,但是小编在mysql命令框使用insert命令向表 ...
- day 88 Vue学习之八geetest滑动验证
本节目录 一 geetest前端web中使用 二 xxx 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 geetest前端web中使用 下载gt文件,官网地址,下面我 ...
- ExcelVBA实现一键生成word文字报告及批量操作[原创]
在很多工作中,经常需要写一些类似的报告,使用同一个模板,只是里面的数据不同,人工操作工程量大且容易出错,如果能用程序直接实现可以省去不少麻烦. 本文使用ExcelVBA实现,主要思路是使用word邮件 ...
- Ajax第一天——入门与基本概念
什么是Ajax Ajax被认为是(Asynchronous JavaScript and XML的缩写).异步的js和xml 异步和同步:同步->类似打电话,接完一个再接下一个:异步:-> ...
- 洛咕 P4528 [CTSC2008]图腾
洛咕 P4528 [CTSC2008]图腾 神题orz. 先约定abcd表示\(1\leq A<B<C<D\leq n\),而且\(y_a,y_b,y_c,y_d\)的排名正好是\( ...