如果从来没有学习过某种编程语言,本书是读者所阅读的第一本编程语言的书籍,我对此倍感荣幸。下面就以此类读者为对象,介绍 Python 中的变量( Variable )。
那么,Python 中的变量是什么意思呢?请读者进入到本地计算机的 Python 交互模式中(参阅2.1.1节),按照如下方式输入:
>>> x = 3.14 # (1)
>>> x # (2)
3.14 # (3)
注释(1)和(2)是输入的内容(其中 # (1)
和 # (2)
不必输入,本书中用这种方式标记相应的行,即“注释(1)”是指注释(1)所标记的一个代码逻辑行 x = 3.14
)。输入注释(1)之后,敲回车键,进入下一个命令行,再输入注释(2),敲回车键,返回了注释(3)所示的值(称为“返回值”)。同样方法,还可以令 x
“等于”其他数,也均可以用注释(2)得到该数字。
而在 Python 中,变量 x
引用了一个数字,注意这个词语:“引用”。此处需要发挥个人的想象力,形象地理解“引用”的含义。以上述代码中的注释(1)为例,如果将 3.14
看做为一个东西(严格术语是“对象”,请参阅2.4节。“东西”是一种通俗的说法,但不严谨,只适用于此处的初步理解),而变量就是一枚标签,注释(1)的作用效果就是将这枚标签贴到 3.14
这个东西上。注释(2)的作用就是通过这枚标签,找到它对应的东西,即得到了返回值。
接续上述代码,继续执行如下操作:
>>> x + 2.1
5.24
如前所述,变量 x
引用了 3.14
,那么 x + 2.1
就实现了 3.14
和 2.1
的求和,返回值是 5.24
——注意,在上述操作中,如果用其他数字与 x
相加,得到了莫名其妙的结果,暂时不用理会,后面会详解(参阅第3章3.4.2节)。
那么,这时候变量 x
是否还在引用 3.14
呢?从逻辑上看,没有对它做任何操作——将标签贴在了那个东西上,并没有对它执行“摘下来”的动作——应该维持原样。
>>> x
3.14
果真如此。
继续下述操作,并尝试用“ Python 中的变量与对象之间是引用关系”这一认识解释操作结果。
>>> x = 3 # (4)
>>> x + 1 # (5)
4
>>> x # (6)
3
注释(4)表示变量 x
引用了 3
;注释(5)完成的实则是 3 + 1
;执行注释(6),返回的是 3
,而不是前面的 3.14
。
如果在交互模式中输入 x = x + 1
会是什么结果?按照前面的分析,从数学角度看,这是不成立的,然而在 Python 中,会看到别样风景。
>>> x = x + 1 # (7)
>>> x # (8)
4
注释(7)是接续前面的注释(6)进行的操作,先看注释(8)返回的结果,变量 x
引用的东西不再是注释(6)中的 3
,而是 4
,这个变化是怎么发生的?应用“ Python 中的变量与对象之间是引用关系”的认识,结合图2-3-1来理解注释(7)的奥妙之处:
x + 1
,它的返回值是 4
,如图2-3-1中的①所示;x
引用上面计算结果,如图2-3-1中的②所示,相当于执行 x = 4
;4
。图2-3-1 变量与对象的关系
Python 的变量除了可以引用数字之外,还可以引用其他任何 Python 对象,读者会随着本书的学习不断理解这句话的含义。
★自学建议 不同编程语言,有不同的命名变量方式。有的编程语言要求先声明变量(同时要指出其类型);有的编程语言不用声明变量,而是“拿过来就用”。这是不同类型编程语言的规定,请读者在学习的时候进行分辨,但无所谓谁“好”谁“坏”。 有些 Python 语言的学习资料中,认为变量是一个“容器”,例如
x = 4
,解释为创建了一个变量——就像一个容器,将4
放到里面(或者说传给它)。本书没有采信这种说法,而是使用了“引用”的概念。对此建议读者暂时不用下结论孰对孰错,可以随着学习的深入自己建立起对此问题的理解。”
特别注意,Python 中的变量不能脱离所引用的对象(即前面所说的“东西”)而单独存在,比如创建一个变量 y
,试图以备后用,就会爆出 NameError
异常(关于异常,参阅第10章)。
>>> y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
这是 Python 中变量的一个特点,请读者使用的时候务必小心。
本节中特别强调的一个认识是“ Python 中的变量与对象之间是引用关系”,在牢固地树立了此观念之后,本书的行文表述中可能会用一些比较简略的说法,比如注释(8)中,变量 x
引用了整数 4
,简化为“ x
变量的值是 4
”,或者用 x
指代所引用的对象等。
在 Python 语言中如果套用数学中变量的命名规则,就会出现2.2节中 a = ["机器学习数学基础", "Python完全自学手册", "数据准备和特征工程"]
这样可读性很差的“丑陋的变量名称”。在 Python 语言中——所有高级编程语言都如此,习惯于用意义明确的英文单词或者单词组合来命名变量,这样做的好处是可读性强——通过名称可知道其含义,胜过任何注释;坏处是拼写的字母多一些,不要吝惜为此而付出的更多次敲击键盘的时间,与可读性相比,那是值得的。
如果使用多个单词,这些单词如何连接也是一个问题,比如:
mywebsite = "www.itdiffer.com"
这里的变量 mywebsite
虽然符合上述的命名建议,但可读性并没有增强,或者说不太“增强”。从自然语言的角度来说,“my website”的可读性才强呢,但是 Python 不允许在名称中有空格:
>>> my website = "www.itdiffer.com"
File "<stdin>", line 1
my website = "www.itdiffer.com"
^
SyntaxError: invalid syntax
禁止有空格是有道理的,观察上面的代码是,能唯一确定写代码的人所命名的变量是my website
还是 website
吗?如果我们不能唯一确定,计算机也如此,故“面对不确定性,拒绝妄加猜测。”(参阅第1章1.4节的“ Python 之禅”)
为了解决这个问题——既要使用多个单词,又要有可读性,还不引入歧义,在编程语言中(包括 Python)通常有如下推荐命名形式(注意,是推荐,而非强制):
myWebsite
、firstUniveristyName
。MyWebsite
、FirstUniversityName
。这种命名形式又称为“大驼峰式”,对应着上面的“驼峰式”则称为“小驼峰式”。_
连接(注意,是英文输入法下的下划线,在英文状态下,按住“ shift ”键,再按“ - ”键),例如:my_website
、first_unviersity_name
。-
连接(注意,是英文输入法下的减号),例如:my-website
、first-university-name
。以上常见的四种变量命名形式,不同的开发团队会根据自己的喜好选择,开发者应该服从团队的规定——内部统一。在本书中,选择使用“蛇形式”,这也是 Python 中比较流行的命名普通变量的形式( Python,即“蟒蛇”,可能与此有关,图2-3-2为其图标)。
图2-3-2 Python 语言的图标
了解了变量的命名形式之后,其名称必须符合如下要求:
变量名称不以数字开头;
变量名称中可以包含英文字母(大写和小写)、数字以及下划线 _
。不允许有其他英文状态下的字符,如“+、-、#、!、@”等,也不能有空格。
一般不使用单个的l
(字母 L
的小写)、O
(字母 o
的大写)、I
(字母 i
的大写)作为变量名称,这也是为了提高可读性,避免误解。
一般不用内置的 Python 函数来命名,这样会导致以后调用该函数的时候无法使用(关于内置函数,参阅第3章3.3.1节)。
不使用 Python 关键词命名。在交互模式,执行下述操作,查看关键词(或称“保留字”)。
变量名称的长度可以任意,但不宜太长。
>>> import keyword
>>> print(keyword.kwlist)
['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', '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']
下表列出若干个变量名称,读者可以自行在交互模式里测试,如此命名会出现什么结果。
变量名称 | 正确与否 | 说明 |
---|---|---|
1abc | 错误 | 不能用数字开头 |
__book__ | 正确 | 允许以下划线开头 |
__book&code__ | 错误 | 不能含有&符号 |
int | 错误 | 不能用 Python 内置对象类型命名 |
class | 错误 | 不能用 Python 关键词 |
按照以上的要求和建议,是不是就能命名出非常“好”的变量了呢?非也。以上仅仅是形式上和个别字符、词语的规定,但具体到一个变量怎么“取名字”,还要靠个人或者团队的其他规定,比如颇受一部分开发者推崇的“匈牙利命名法”,就规定了一些命名规则(开发者对“匈牙利命名法”并没有完全达成共识,仁者见仁智者见智,此处不单独对此进行介绍,供读者自行探究)。
前面所讨论的是 Python 中的普通变量,后续还会遇到其他变量,比如全局变量,其命名形式会有所差别,主要是为了突出它不是普通变量。命名的问题不仅仅局限于变量,还有函数、类、模块等,这些内容在本书后续章节中会逐步介绍。
★自学建议 对变量、函数、类、模块等命名,是一个兼有科学性和艺术性的问题,关系到代码的可读性。对于初学者而言,以下几点请注意: