【Python学习】python学习手册--第六章 动态类型简介

本文深入探讨了Python的动态类型特性,解释了变量、对象和引用的概念,并详细说明了对象的创建、引用计数及垃圾回收机制。此外还介绍了变量间的共享引用及如何实现对象的拷贝。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一些静态编译语言中,你会看到一些对变量类型的声明(比如C语言,Java语言中,在使用变量之前,都需要对变量的类型进行声明)。但是在python中,就可以直接对变量赋值,省略了变量类型的声明这一步。这就是Python动态类型模型的领域。

变量、对象和引用

  • 变量创建:当在使用变量赋值时,第一次赋值一个变量名就会产生新的变量名,当之后的赋值操作,就会改变这个变量。
  • 变量类型:变量永远不会有类型的约束,之所以变量有类型,是因为变量所指向的对象有类型,而不是变量本身有类型。变量只是在一个时间段内,引用了一个特定类型的对象而已。
  • 变量使用:变量在表达式中被使用时,会被立即替换成为它所引用的对象。任何一个变量都必须在被使用之前被赋值。否则在使用时,引用空变量会产生错误。

Python中所谓的对象类型是与对象相关联的,而不是编程时常见的变量。如果将变量名和对象划分开来,动态类型是很容易理解的。

>>> a=9

这里Python程序执行就有三个大概步骤:

  1. 创建一个对象“3”。
  2. 创建一个变量名a(如果变量没有被创建的话)。
  3. 将变量a和对象“3”链接起来。

实际的效果就像图下的结构所示:
这里写图片描述
从变量到对象的链接,在Python中称为引用,在内存中以指针的形式出现。
从技术层面上来讲就是:

  • 变量是一个系统表的元素,拥有指向对象的连接的空间,变量名没有类型
  • 对象是分配的一块内存,有足够的空间来表示它所代表的值
  • 引用是自动形成的从变量到对象的指针

Python内部上,缓存了不变的对象,后面新变量可以对相同的对象进行复用。从技术来讲,每个对象都有两个标准的头部信息:一个类型标志符去标识这个对象类型,以及一个引用的计数器,记载着引用这个对象的变量个数,这决定了Python是否需要对这个对象进行内存收回。

对象的垃圾收集

在python中,如果一个变量被赋予了一个新的对象,那么这个变量之前所引用的旧对象就会被回收(如果该对象也没有被其它变量引用时),这种自动回收对象空间的技术就是垃圾收集。原来无用的旧对象会被放入自由内存空间池,等待被后来的对象使用。
在技术上,Python的每个对象都会有头部信息,其中计数器就记载这引用该对象的变量数量,当数字变为零时,Python就会对该对象内存空间进行回收。可以使用sys.getrefcount来显示对象被引用的数量。

>>> help(sys.getrefcount)
Help on built-in function getrefcount in module sys:

getrefcount(...)
    getrefcount(object) -> integer

    Return the reference count of object.  The count returned is generally
    one higher than you might expect, because it includes the (temporary)
    reference as an argument to getrefcount().
>>> a="lxm"
>>> sys.getrefcount("lxm")       
3
>>> b="lxm"
>>> sys.getrefcount("lxm")
4
>>> c=b
>>> sys.getrefcount("lxm")
5
>>> 

这种回收机制的好处就是让python更加简洁,与c/c++语言相比,少了很多基础代码。

共享引用

当两个变量都引用相同的对象时,它们都会指向相同的内存空间,这在python中叫做共享引用

>>> a=3
>>> b=a
>>> 

这里写图片描述

原处修改

当有共享引用时,就需要考虑如果对象改变了,那么指向该对象的所有变量都会变化。(当然有些对象类型(数字,字符串,元组)具有不可变性,这样的问题就不存在)。

>>> a=[1,2,3,4]
>>> b=a
>>> a=12                #变量a重新指向了新的
>>> a
12
>>> b
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a=b
>>> a
[1, 2, 3, 4]
>>> a.pop()             #列表具有可变性,当对象改变时,指向该对象的变量b也会随之一起改变。
4
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>> 

如何使两个变量指向不同内存空间的相同对象呢?可以使用分片来达到“拷贝”的效果:

>>> a
[1, 2, 3]
>>> b=a[:]
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b         #此时变量b与a不是指向同样的内存空间了,它们指向的是两个不同的内存空间。分片效果实现了拷贝作用
[1, 2, 3]
>>> 

其它类型对象(不能使用切片实现拷贝的)可以使用Python内置copy()方法实现拷贝(需要导入)。
import copy
x=copy.copy(Y)
x=copy.deepcopy(Y) #可以拷贝对象内嵌套的对象。

对象相等或相同

变量是否是指向的同一个对象,可以用is 表达式来判断:

>>> a=[1,2,3,4]
>>> b=[1,2,3,4]
>>> a is b              #两个不同的内存空间,即两个变量指向的不同对象
False
>>> a == b
True
>>> a.pop()
4
>>> a
[1, 2, 3]
>>> b
[1, 2, 3, 4]           #指向的对象不同,变量b不会随之改变
>>> a=b
>>> a is b             #两个变量都指向相同的对象
True
>>> a == b
True
>>> 

总结

python中的动态类型,没有了对变量类型的约束,让Python更加灵活,在开发时更加得心应手。对动态类型的了解,对Python的深入理解有更多帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值