【Python】python动态类型
在python中,省去了变量声明的过程,在引用变量时,往往一个简单的赋值语句就同时完成了,声明变量类型,变量定义和关联的过程,那么python的变量到底是怎样完成定义的呢?
动态类型
python使用动态类型和他提供的多态性来提供python语言的简洁灵活的基础。在python中我们是不会声明所使用对象的确切类型的。所谓的python动态类型,就是在程序运行的过程中自动决定对象的类型。
对象、变量和引用
当我们在赋值一个变量时,在python中其实自动做了很多事情。
1.创建变量:当代码第一次赋值给一个变量时就创建了这个变量,在之后的赋值过程关联值,python在代码运行之前先检验变量名,可以当成是最初的赋值创建变量。
2.变量声明:python中类型只存在于对象中,而不是变量,变量是通用的,他只是在程序的某一段时间引用了某种类型的对象而已,比如定义a =1 ,a = 'a',一开始定义了变量a为指向了整型的对象,然后变量又指向了字符串类型的变量,可见,变量是不固定的类型。
3.变量使用:变量出现在表达式中就会马上被对象所取代,无论对象是什么内类型,变量在使用前必须要先定义。
值得注意的是,变量必须在初始化名字之后才能更新他们,比如计数器初始化为0,然后才能增加他。
也就是说,当我们给变量赋值的时候,比如a=3,python执行三个不同操作去完成赋值。
1.创建一个对象代表3,
2.如果程序中没有变量a,则创建他。
3.将变量与对象3连接起来。
变量与对象是连接关系,它们存储在内存的不同位置,如果有列表嵌套这样大的对象,对象还连接到它包含的对象。这种从变量到对象的连接称为引用。
变量的引用以内存中的指针形式实现。一旦变量被使用,那么python自动跟变量的对象连接。具体来说:
1.变量是系统表的元素,他指向对象存放的地址空间。
2.对象是分配的一块内存,地址可被连接,有足够大空间代表对象的值,
3.引用的过程自动完成变量指向对象地址的过程,即从变量到对象的指针。
对象的垃圾回收
每个对象都有两个标准头部信息,一个是类型标志符,用于标记对象类型,另一个是引用计数器,用来决定是不是可回收对象。很显然,在python中只有对象才有类别区分,变量不过是引用了对象,变量并不具有类别区分,他只是在特定时间引用某个特定对象。
对于引用计数器的使用,则关联到python的垃圾回收机制,当当一个变量名赋予了一个新的对象,那么之前旧的对象占用的地址空间就会被回收。旧对象的空间自动放入内存空间池,等待后来的对象使用。
计数器在垃圾回收的过程中有事如何工作的呢?计数器记录的是当前指向对象的引用数目,如果在某时刻计数器设置为0,则表示未被引用,name这个对象的内存空间就会收回。
对象的垃圾回收有着很大的意义,这使得我们在python中任意使用对象而且不需要考虑释放空间,省去了C与C++中大量的基础代码。
共享引用(深浅拷贝的缘由)
当一个变量使用多个对象时,旧的对象会被垃圾收回,那么变量共享变量的对象有事一种什么样的类型呢?
a=‘hello world’
b=a
print(b)
运行结果:
hello world
值得一提的是,这里b变量引用的a作为值,根据python中赋值是以对象来完成的,所以b引用的应该是a变量指向的对象地址的值,故可以判断,改变a指向的对象并不会影响b的值。
a=‘hello world’
b=a
a='new hello world'
print(a)
print(b)
运行结果:
new hello world
hello world
python中变量总是一个指定对象的指针,而不是能够改变内存区域的标签,即给一个变量赋新的值,不是替换一个对象原始值,而是创建一个新得对象供变量引用。
当然这条只限于对象的类型不可改变,如果引用对象是像列表一样可供修改的对象那结果如何呢?
a=[1,2,3]
b=a
a.append(4)
print(a)
print(b)
运行结果:
[1, 2, 3, 4]
[1, 2, 3, 4]
结果很显然,对于可变类型对象,变量不会创建一个显得对象,而是沿用之前的对象,即使对象已经被改变了。可以简单的理解为,两个对象同时指向了一个列表的内存地址,而列表又映射了里面各元素的内存地址,变量的共享并不关注列表的改变,他们只关心列表的内存空间是否改变,所以,可变对象在引用时自身可以改变,所以不需要创建新的对象,所以共享对象会随之前对象的变化而变化。
这其实是我们不希望看到的。我们可以使用拷贝对象创建引用:
a=[1,2,3]
b=a[:]
a.append(4)
print(a)
print(b)
运行结果:
[1, 2, 3, 4]
[1, 2, 3]
这种方法并不适用于不可索引但是可变的字典与集合,所以python的copy模块用于变量引用:
import copy
a=[1,2,3,[1,2]]
b=copy.copy(a)
c=copy.deepcopy(a)
d=a
a.append(4)
a[3][0]=5
print(a)
print(b)
print(c)
print(d)
运行结果:
[1, 2, 3, [5, 2], 4]
[1, 2, 3, [5, 2]]
[1, 2, 3, [1, 2]]
[1, 2, 3, [5, 2], 4]
共享引用的补充
其实是关于垃圾回收的一点补充,对于一些小的整数或字符串,并不像我们说的那样计数器标记为0就被收回。这和python的缓存机制有关。对于一般的对象,python适用于垃圾收回。
a=[1,2,3]
b=[1,2,3]
c=a
print(a == c)
print(a == b)
print(a is c)
print(a is b)
运行结果:
True
True
True
False
对于小的整数与字符串则不同:
a=111
b=111
c=a
print(a == c)
print(a == b)
print(a is c)
print(a is b)
运行结果:
True
True
True
True
在python中,任何东西都是在赋值与引用中工作的,对于理解python动态类型,在以后的工作与学习时是有很大帮助的,这是python唯一的赋值模型,所以准确的理解与应用十分有必要。不对类型作约束,这使得python代码极为灵活,高效,并且省去了大量的代码,极为简洁,所以python是这样一门有艺术的编程。
【Python】python动态类型的更多相关文章
- python动态类型
在python中,省去了变量声明的过程,在引用变量时,往往一个简单的赋值语句就同时完成了,声明变量类型,变量定义和关联的过程,那么python的变量到底是怎样完成定义的呢? 动态类型 python使用 ...
- Python基础系列讲解—动态类型语言的特点
前言 在C语言中变量所分配到的地址是内存空间中一个固定的位置,当我们改变变量值时, 对应内存空间中的值也相应改变.在Python中变量存储的机制是完全不一样的,当给一个变量赋值时首先解释器会给这个值分 ...
- Python 语言特性:编译+解释、动态类型语言、动态语言
1. 解释性语言和编译性语言 1.1 定义 1.2 Python 属于编译型还是解释型? 1.3 收获 2. 动态类型语言 2.1 定义 2.2 比较 2. 动态语言(动态编程语言) 3.1 定义 3 ...
- 全面理解Python中的类型提示(Type Hints)
众所周知,Python 是动态类型语言,运行时不需要指定变量类型.这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发 ...
- Python Type Hint类型注解
原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...
- 初识Python - Python的历史(转)
声明: 本文转自维基百科 如有意见请联系删除 综述 该编程语言 的Python是在20世纪80年代末的设想,和实施是在1989年12月开始由吉多·范罗苏姆在CWI在荷兰的继任者农行能够异常处理,并与接 ...
- Python进阶09 动态类型
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 谢谢TeaEra, 猫咪cat 动态类型(dynamic typing)是Pyth ...
- python 数据类型(sequence 序列、dictionary 词典、动态类型)
文章内容摘自:http://www.cnblogs.com/vamei 1.sequence 序列 sequence(序列)是一组有顺序的元素的集合 (严格的说,是对象的集合,但鉴于我们还没有引入“对 ...
- 《Python 学习手册4th》 第六章 动态类型简介
''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书)“重点笔 ...
随机推荐
- LeetCode初级算法的Python实现--链表
LeetCode初级算法的Python实现--链表 之前没有接触过Python编写的链表,所以这里记录一下思路.这里前面的代码是和leetcode中的一样,因为做题需要调用,所以下面会给出. 首先定义 ...
- 16-oauth2-oidc-Client实现
1-新建.net core2.1 mvc网站 2-在Startup.config文件增加相关代码, 下面代码已经配置好oidc客户端了,并设置本mvc启动ip为5009 public void Con ...
- Codeforces Round #460 (Div. 2) 前三题
Problem A:题目传送门 题目大意:给你N家店,每家店有不同的价格卖苹果,ai元bi斤,那么这家的苹果就是ai/bi元一斤,你要买M斤,问最少花多少元. 题解:贪心,找最小的ai/bi. #in ...
- 成都Uber优步司机奖励政策(4月5日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 成都Uber优步司机奖励政策(2月23日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- day 10 形态学处理 膨胀
#-*- coding:utf-8 -*- #1.导入包 import cv2 import numpy as np #2.导入图片 img = cv2.imread('home.jpg',0) #3 ...
- create-react-app react-redux项目 配置模块热更新hmr
HRM并不是create-react-app专属的,提供一篇博客介绍hrm http://chrisshepherd.me/posts/adding-hot-module-reloading-to-c ...
- 破解IDEA注册码,设置 license server一直有效不过期
破解的详细过程: 1.从下面地址下载一个jar包,名称是 JetbrainsCrack-2.10-release-enc.jar 下载地址是http://idea.lanyus.com/,进去之后点 ...
- 【cover-view、cover-image】 覆盖组件说明
cover-view.cover-image 这两类覆盖组件用于显示在一些特殊组件上方(map.video.canvas.camera.live-player.live-pusher). 这类组件一般 ...
- Vue 编程之路(二)——跳转页面传值
最近公司的一个项目中使用 Vue 2.0 + element UI 实现一个后台管理系统的前端部分,属于商城类型.其中我负责的部分有一项需要跳转页面,由于跳转前的页面是多个组件构成的,所以在跳转页面的 ...