RealPython基础教程:一文理解 Python 中的变量

变量让程序活起来,不再千人一面。

realpython.cn 正在翻译《RealPython 基础教程》,敬请关注!】

我们在之前的文章《Python 基本数据类型介绍》中了解了如何创建各种基本类型的数据,但是我们的例子中使用的都是“字面量”或者“常量”。

>>> print(5.3)
5.3

这显然不适于复杂的实用程序中,我们需要定义能够在程序执行过程中可以变化的数据。

通过本文,你将了解到:

1,Python 中的所有数据元素都可通过抽象的对象(object)来描述

2,你将学会如何通过符号名称(变量)来操作这些对象。


【变量的赋值】

我们可将变量视作附着在一个特定对象上的名称。

在 Python 中,变量不必提前声明或定义。这和其他一些编程语言不同,在那些编程语言里,变量必须先声明才可以使用。

创建变量很简单,只需要为这个名称赋一个值就行了,然后你就可以使用它了。

Python 使用等号(=)为变量赋值:

>>> n=300

这个赋值语句的意思是:n 被赋值为 300.

赋值完成后,n 就可以被用作语句或者表达式中了。其值也会被更新。

>>> print(n)
300

我们也可以不使用 print() 函数,直接在 Python 解释器命令提示符窗口中输入 n 来打印其值。

>>> n
300

可以给 n 重新赋值。

>>> n=1000
>>> n
1000

Python 允许链式赋值,这让我们可以同时为多个变量赋相同的值。

>>> a = b = c = 300
>>> a
300

>>> b
300

>>> c
300

【Python 变量的类型】

数据类型是对数据上可执行操作的约定。

在很多编程语言中,变量是静态类型。其含义是,变量在初始化时需要声明为一个特定的类型,在后续的使用中也只能将相同类型的值赋给这个变量。静态类型的变量,意味着在其上只能执行类型专有的操作。

而 Python 中的变量不受此限制。变量可以被赋予一个类型的值,之后再被赋予另一个类型的值。

>>> var = 23.5
>>> var
23.5
>>> type(var)
<class 'float'>

>>>
>>> var = "now i'm a string"
>>> var
"now i'm a string"
>>> type(var)
<class 'str'>

在实际应用中,动态改变变量的类型可能并非一个好的行为,这会引起理解和运行上的混乱。


【对象引用】

当我们创建一个变量时,Python 解释器到底执行了什么操作?

了解这个问题的答案很重要,因为这和你在其他语言中理解的原来稍微有点不一样。

Python 是一个高度面向对象的语言。Python 程序中的每个数据元素都是一个特定类(class)的实例对象(object)。

考虑下边这段简单的代码:

>>> print(300)
300

当执行 print(300) 这条语句时,Python 解释器会做以下 3 个工作:

  • 创建一个整数对象

  • 为这个整数对象赋值 300

  • 将这个整数对象输出到控制台

使用 type() 函数就能看出为这个常量 300 创建了一个整数对象:

>>> type(300)
<class 'int'>

Python 变量其实只是一个名称而已,它是指向某个对象的引用或者指针,是“贴在这个对象上的一个标签”。

一旦变量被赋值,你就可以通过变量名来引用它指向的对象,变量拥有的数据实际上是被保存在这个对象中。

仍以这个简单代码为例:

>>> n=300

这个赋值语句创建了一个值为 300 的整数对象,并将变量 n 指向这个对象。

你可以这样理解:喏,整数为 300 的对象,给你贴个标签,你现在叫 n 了。

以下代码就可看出 n 指向了一个值为 300 的 int 类型的对象:

>>> print(n)
300

>>> type(n)
<class 'int'>

再看下边这条语句:

>>> m = n

那么,执行这条语句时又发生了什么?

Python 并没有为 m 创建一个新的对象,而只是建立了一个新的名字 m,并将这个名字指向了 n 指向的对象。

现在,值为 300 的整数对象身上贴了两个标签:n 和 m。

我们接着执行以下操作:

>>> m=400

这时,Python 才又创建了一个新的值为 400 的整数对象,并将名字 m 指向这个对象。

300 和 400 两个整数对象各有一个标签。

最后,我们再执行一条语句:

>>> n='foo'

这会导致 Python 创建一个新的字符串对象,其值为 foo,并将名字 n 指向这个字符串对象。

因为变量是一个名字、一个标签,它可以被轻易地从一个对象贴往另一个对象,不管这些对象是否属于同一类型。

你也能够看到,n 指向字符串对象后,不再有任何名字指向整数 300 这个对象,我们无法再对其进行访问,它变成一个“孤儿”了!

这里简单介绍一下 Python 对象的生命周期。

一个对象的生命周期始于它被初始创建时,那时至少有一个引用指向它。在后续的过程中,会有其他引用指向或不再指向它,也就是说,指向一个对象的引用数目是动态变化的。但只要还有一个引用指向它,这个对象就保持存活状态。

当对象的引用数减少到 0 时,这个对象就变为不可访问状态了。这也意味着其生命周期即将结束。Python 解释器会留意到这个对象不可访问,将其占用的内存重新标记为可用。

这个过程在计算机领域称为:垃圾回收。


【对象身份(id)】

Python 为每一个创建的对象分配一个数字,这个数字可唯一地标识这个对象。Python 解释器确保不会有任何两个对象在其生命周期内拥有相同的标识。一旦对象的引用计数减至 0,伴随着对象被回收,它的标识数字也会被回收,并可重用。

Python 内置的 id() 函数可返回一个对象的标识。我们可用这个函数来判断两个变量是否指向了同一个对象。

>>> n=300
>>> m=n
>>> id(n)1455946814064
>>> id(m)1455946814064
>>>
>>> m=400
>>> id(m)
1455946814256

这也验证了我们上边对“变量是对象的引用”的分析。

有了这些概念后,下边这段代码执行结果很容易理解:

>>> m=300
>>> n=300
>>> id(m)
1455943043248
>>> id(n)
1455946814256

m 和 n 指向了不同的整数对象。

但是,下边这段代码执行结果该如何解释?

>>> m=30
>>> n=30
>>> id(m)
140723401618608
>>> id(n)
140723401618608

m 和 n 的值都是30,它们的 id 竟然也是相同的!

原来,出于优化目的,Python 解释器在启动时自动创建了一批数值介于 [-5, 256] 之间的“小整数”对象,这些对象会在程序运行过程中被重用。此称为“小整数缓存”。

所以,当你给变量赋值 [-5, 256] 之间的整数时,具有相同值的变量实际上会指向同一个对象。


【变量命名】

在我们使用过的例子里,我们用到的变量名都是诸如 m、n 这样简短的名字。而变量的名字其实是可以很长并且具有明确意义的。合理的命名变量会让人一眼就明白其含义,有助于代码的理解和维护。

Python 支持任意长度的变量名,并且变量名可以包含大小写字母(A-Z、a-z)、数字(0-9)和下划线(_)。一个限制是:变量名首字符不得是数字。

以下是一些合法的变量名:

>>> name='Bob'
>>> Age=54
>>> has_W2=True
>>> print(name, Age, has_W2)
Bob 54 True

而以数字开头的变量名则会引起语法错误:

>>> 1099_filed =
False
File "<stdin>", line 1
1099_filed = False
^SyntaxError: invalid token

另外,变量名也是大小写敏感的,大写和小写被视作不同的字符。

以下几个变量应视为不同的变量:

>>> age=1
>>> Age=2
>>> aGe=3
>>> AGE=4
>>> a_g_e=5
>>> _age=6
>>> age_=7
>>> _AGE_=8

如果你在同一程序中同时使用了这几个形式不同的 age 给变量命名,这是不被提倡的。这会引起混淆,在不同地方遇到 age 时需要绞尽脑汁来思考它的确切含义,也会给代码维护者带来很大麻烦。

变量名称应是自描述的,能清晰地表明变量是用来做什么的。

假如你有一个表示毕业生数目的变量,那么你可以使用下边这几个变量名:

>>> numberofcollegegraduates = 2500
>>> NUMBEROFCOLLEGEGRADUATES = 2500
>>> numberOfCollegeGraduates = 2500
>>> NumberOfCollegeGraduates = 2500
>>> number_of_college_graduates = 2500

这些名称明显好于 m、n,你可以从中读出它们表示的是什么。

这些“好”的变量名可读性也不完全相同,尤其是前两个,比较难识别其中的单词。

采用何种命名方式因人而异,不同组织也有自己的规则。

最常见的 3 种多单词变量命名方式为:

  • 驼峰命名法

    首字母小写,其余单词首字母大写:numberOfCollegeGraduates

  • Pascal 命名法

    所有单词首字母大写:NumberOfCollegeGraduates

  • 蛇形命名法

    字母小写,单词间以下划线(_)分隔:number_of_college_graduates

除了变量,Python 中的其他标识符(函数名、类名、模块名等)也需要采用合理和一致的命名方式。

Python 官方代码风格(PEP 8)建议的命名风格为:

  • 使用蛇形命名法为变量和函数命名

  • 使用 Pascal 命名法为类命名


【关键字】

对标识符(变量、函数、类、模块等的名称)命名还有一个约束:不得使用 Python 关键字来命名。

Python 关键字是 Python 语言保留的一些实现语言层面功能的词语。用户使用这些词语给自定义标识符命名会导致语法错误。

>>> for = 3
File "<stdin>", line 1
for = 3
^SyntaxError: invalid syntax

这些关键字包括:

False、None、True、and、as、assert、break、class、continue、def、del、elif、else、except、finally、for、from、global、if、import、in、is、lambda、nonlocal、not、or、pass、raise、return、try、while、with、yield


【结语】

本文全面介绍了 Python 变量的基础知识,包括对象引用和标识、标识符命名等。

现在我们已对 Python 数据类型有了很好的理解,并且能够通过变量来创建这些不同类型的数据对象了。

接下来,我们会学习如何在表达式中使用这些对象,并了解各种操作符的用法。

realpython.cn 正在翻译《RealPython 基础教程》,敬请关注!

原文地址:https://www.cnblogs.com/rd-log/p/14355837.html