返回介绍

第6章 动态类型简介

发布于 2024-01-29 22:24:17 字数 2610 浏览 0 评论 0 收藏 0

在上一章学习了Python数字类型,本章开始对Python的核心对象类型进行深入探索。我们将会在下一章继续对象类型之旅,在我们继续学习之前,掌握Python编程中最基本的概念是很重要的。动态类型以及由它提供的多态性,这些概念无疑是Python语言简洁性和灵活性的基础。

正像本书稍后介绍的那样,在Python中,我们并不会声明脚本中使用的对象的确切类型。事实上,程序甚至可以不在意特定的类型;相反地,它们能够自然地适用于更广泛的场景下。因为动态类型是Python语言灵活性的根源,让我们先简要地看一下这个模块。

缺少类型声明语句的情况

如果你有学习静态编译类型语言C、C++或Java的背景,学到这里,你也许会有些困惑。到现在为止,我们使用变量时,都没有声明变量的存在和类型,但变量还可以工作。例如,在交互会话模式或是程序文件中,当输入a=3时,Python怎么知道那代表了一个整数呢?在这种情况下,Python怎么知道a是什么?

一旦你开始问这样的问题,就已经进入了Python动态类型模型的领域。在Python中,类型是在运行过程中自动决定的,而不是通过代码声明。这意味着没有必要事先声明变量(只要记住,这个概念实质上对变量、对象和它们之间的关系都适用,那么这个概念也就很容易理解并掌握了)。

变量、对象和引用

就像本书已使用过的很多例子一样,当在Python中运行赋值语句a=3时,即使没有告诉Python将a作为一个变量来使用,或者没有告诉它a应该作为一个整数类型对象,但一样也能工作。在Python语言中,这些都会以一种非常自然的方式完成,就像下边这样:

变量创建

一个变量(也就是变量名),就像a,当代码第一次给它赋值时就创建了它。之后的赋值将会改变已创建的变量名的值。从技术上来讲,Python在代码运行之前先检测变量名,可以当成是最初的赋值创建变量。

变量类型

变量永远不会有任何的和它关联的类型信息或约束。类型的概念是存在于对象中而不是变量名中。变量原本是通用的,它只是在一个特定的时间点,简单地引用了一个特定的对象而已。

变量使用

当变量出现在表达式中时,它会马上被当前引用的对象所代替,无论这个对象是什么类型。此外,所有的变量必须在其使用前明确地赋值,使用未赋值的变量会产生错误。

总而言之,变量在赋值的时候才创建,它可以引用任何类型的对象,并且必须在引用之前赋值。这意味着,不需要通过脚本声明所要使用的名字,但是,必须初始化名字然后才能更新它们;例如,必须把计数器初始化为0,然后才能增加它。

这种动态类型与传统语言的类型相比有明显的不同。刚入门时,如果清楚地将变量名和对象划分开来,动态类型是很容易理解的。例如,当我们这样说时:

至少从概念上来说,Python将会执行三个不同的步骤去完成这个请求。这些步骤反映了Python语言中所有赋值的操作:

1.创建一个对象来代表值3。

2.创建一个变量a,如果它还没有创建的话。

3.将变量与新的对象3相连接。

实际的效果是如图6-1所示的一个在Python中的内部结构。如图6-1所示,变量和对象保存在内存中的不同部分,并通过连接相关联(这个连接在图6-1中显示为一个箭头)。变量总是连接到对象,并且绝不会连接到其他变量上,但是更大的对象可能连接到其他的对象(例如,一个列表对象能够连接到它所包含的对象)。

图 6-1 变量名和对象,在运行a=3后。变量a变成对象3的一个引用。在内部,变量事实上是到对象内存空间(通过运行常量表达式3而创建)的一个指针

在Python中从变量到对象的连接称作引用。也就是说,引用是一种关系,以内存中的指针的形式实现[1]。一旦变量被使用(也就是说被引用),Python自动跟随这个变量到对象的连接。这实际上比术语所描述的要简单得多。以具体的术语来讲:

·变量是一个系统表的元素,拥有指向对象的连接的空间。

·对象是分配的一块内存,有足够的空间去表示它们所代表的值。

·引用是自动形成的从变量到对象的指针。

至少从概念上讲,在脚本中,每一次通过运行一个表达式生成一个新的值,Python都创建了一个新的对象(换言之,一块内存)去表示这个值。从内部来看,作为一种优化,Python缓存了不变的对象并对其进行复用,例如,小的整数和字符串(每一个0都不是一块真正的、新的内存块,稍后会介绍这种缓存行为)。但是,从逻辑的角度看,这工作起来就像每一个表达式结果的值都是一个不同的对象,而每一个对象都是不同的内存。

从技术上来讲,对象有更复杂的结构而不仅仅是有足够的空间表示它的值那么简单。每一个对象都有两个标准的头部信息:一个类型标志符去标识这个对象的类型,以及一个引用的计数器,用来决定是不是可以回收这个对象。要理解这两个头部信息对模型的影响力,我们需要继续学习下去。

[1]有C语言背景的读者可能会发现,Python的引用类似于C的指针(内存地址)。事实上,引用是以指针的形式实现的,通常也扮演着相同的角色,尤其是那些在原处修改的对象(我们将在稍后部分进行讨论)。然而由于在使用引用时会自动解除引用,你没有办法拿引用来做些什么:这种功能避免了许多C可能出现的Bug。你可以把Python的引用想成C的void指针,每当使用时就会自动运行下去。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文