【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是这样一门有艺术的编程。

时间: 2024-08-28 00:53:50

【Python】python动态类型的相关文章

Python<9>动态类型简介

动态类型以及它提供的多态性,无疑是Python语言简洁性和灵活性的基础. 一.变量 <1>变量创建 一个变量a,当代码第一次给它赋值时就创建了它,之后的赋值将会改变已创建的变量名的值. <2>变量类型 变量永远不会有任何的和它关联的类型信息或约束.变量原本是通用的,它只是在一个特定的时间点,简单的引用了 一下特定的对象而已. <3>变量使用 当变量出现在表达式中,它会马上被当前引用的对象所替代(对象是有类型的).此外所有的变量必须在使用前明确的 赋值,使用未赋值的变量会

Python的动态类型

动态类型:                                                      在python中,类型是在运行过程中自动决定的,而不是通过代码声明的. 变量:                                                                                     变量是一个系统表的元素,拥有指向对象的连接的空间 python中,类型的概念是存在于对象中的,而不是变量中,变量是通用的. 变量的使用

python笔记2 python对象的动态类型

Python中的一切都是对象,并且这些对象都是Python的组成部分,即是内置对象,和python一同产生. 从更正式的角度来讲,在P ython中,数据以对象的形式出现一一无论是Py t hon提供的内置对象,还是使用Python或是像C扩展库这 样的扩展语言工具创建的对象.尽管在以后才能确定这一概念,但对象无非是内存中的一部分,包含数值和相关操作的集合. 内置对象 对象类型 例子常量/创建 数字 1234, 3.1415, 3+4j, Decimal. Fraction 字符串 'spam'

编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别

最近在研究Python和Erlang.反复提到动态类型语言.动态语言.解释型语言这些概念.这些概念很生涩,在这里做一个总结. 编译型语言和解释型语言 1.编译型语言 需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言.一般需经过编译(compile).链接(linker)这两个步骤.编译是把源代码编译成机器码,链接是把各个模块的机器码和依赖库串连起来生成可执行文件. 优点:编译器一般会有预编译的过程对代码进行优化.因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行

【转载】编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别

编译型语言和解释型语言 1.编译型语言 需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言.一般需经过编译(compile).链接(linker)这两个步骤.编译是把源代码编译成机器码,链接是把各个模块的机器码和依赖库串连起来生成可执行文件. 优点:编译器一般会有预编译的过程对代码进行优化.因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高.可以脱离语言环境独立运行. 缺点:编译之后如果需要修改就需要整个模块重新编译.编译的时候根据对应的运行环境生成机器码,

初识Python - Python的历史(转)

声明: 本文转自维基百科 如有意见请联系删除 综述 该编程语言 的Python是在20世纪80年代末的设想,和实施是在1989年12月开始由吉多·范罗苏姆在CWI在荷兰的继任者农行能够异常处理,并与接口阿米巴操作系统.Van Rossum是Python的主要作者,他在决定Python方向方面的持续核心作用体现在Python社区给予他的称号,即仁慈的生活独裁者(BDFL).Python以BBC电视节目Monty Python的Flying Circus命名. Python 2.0于2000年10月

python学习笔记17(动态类型)

动态类型 在我们接触的对象中,有一类特殊的对象,是用于存储数据的,常见的该类对象包括各种数字,字符串,表,词典.在C语言中,我们称这样一些数据结构为变量,而在Python中,这些是对象. 对象是储存在内存中的实体.但我们并不能直接接触到该对象.我们在程序中写的对象名,只是指向这一对象的引用(reference). 引用和对象分离,是动态类型的核心.引用可以随时指向一个新的对象: a = 3 a = 'python' 第一个语句中,3是储存在内存中的一个整数对象,通过赋值,引用a指向对象3. 第二

Python 动态类型

Python 动态类型 1.Python中,类型是在运行过程中自动决定的,并不需要提前在代码中声明. 2.所有变量必须在使用前明确的赋值,否则将会产生错误.#例:NameError: name 'a' is not defined 3.赋值语句 a=3 代表了:创建一个对象代表3:创建一个变量a:将变量与新的对象3相连.实际上是到对象内存空间的一个指针! 4.上面的第3条可翻译为:变量是一个系统表的元素,拥有指向对象的链接的空间:对象是分配的一块内存,有足够空间来表示他们所代表的值:引用是自动形

python动态类型

python是动态语言.不需要事先声明变量类型,同一变量可以被赋值为不同的对象类型. 变量.对象.引用 变量创建 python的变量不需要声明,当代码第一次给其赋值时就创建它. 变量赋值 举例说明,赋值语句 "a = 3".一般而言赋值过程如下: 创建被赋值的对象,即在内存中开辟一块空间,用于保存对象的信息.本例来说是一个整数对象3. 如果变量名之前没有被定义过,创建变量名,'a'.如果变量名存在,则跳过. 建立变量名和被赋值对象之间的引用.引用类似于c语言的指针. 以上过程适用于所有