2.3 变量和关键字
编程语言最强大的功能之一是操纵变量。变量(variable)是一个需要熟知的概念,如果你觉得数学让你抓狂,而担心编程语言中的变量也会让你抓狂,这倒没有必要,因为Python中的变量其实很好理解,变量就是代表某个值的名字。
2.3.1 变量
把一个值赋值给一个名字,这个值会存储在内存中,这块内存就称为变量。在大多数语言中,把这种操作称为“给变量赋值”或“把值存储在变量中”。
比如,Python快乐学习班的同学乘坐“集合号”大巴出去游玩,大巴是一个实实在在存在的物体,要占据空间,而“集合号”是我们给它的一个名字,这个名字可以更改为“空间一号”或是其他。在这里,大巴相当于值,“集合号”相当于变量。
在Python中,变量指向各种类型值的名字,以后再用到这个值时,直接引用名字即可,不用再写具体的值。比如对Python快乐学习班的同学说上“集合号”了,读者就都知道要上大巴了。
变量的使用环境非常宽松,没有明显的变量声明,而且类型不是必须固定。可以把一个整数赋值给变量,也可以把字符串、列表或字典赋给变量。比如这里“集合号”指的是一辆大巴,但我们同样可以用“集合号”指代一艘船、一架飞机或一栋建筑等。
那什么是赋值呢?
在Python中,赋值语句用等号(=)表示,可以把任意数据类型赋值给变量。比如,要定义一个名为xiaomeng的变量,对应值为XiaoMeng,可按下述方式操作:
>>> xiaomeng = 'XiaoMeng' >>>
提示
字符串必须以引号标记开始,并以引号标记结束。
此操作解释:xiaomeng是我们创建的变量,=是赋值语句,XiaoMeng是变量值,变量值需要用单引号或双引号标记。整句话的意思是:创建一个名为xiaomeng的变量并给变量赋值为XiaoMeng(注意这里的大小写)。
这里读者可能会疑惑,怎么前面输入后按回车键就能输出内容,而在上面的示例中按回车键后没有任何内容输出,只是跳到输入提示状态下。
在Python中,对于变量,不能像数据类型那样,输入数值就立马能看到结果。对于变量,需要使用输出函数。还记得前面讲的print()吗?print()是输出函数,上面的示例中没有使用输出函数,屏幕上当然不会有输出内容。要有输出应该怎么操作呢?我们尝试如下:
>>> print(xiaomeng) XiaoMeng
成功打印出了结果。但为什么输入的是print(xiaomeng),结果却输出XiaoMeng呢?这就是变量的好处,可以只定义一个变量名,比如名为xiaomeng的变量,把一个实际的值赋给这个变量,比如实际值XiaoMeng,计算机中会开辟出一块内存空间存放XiaoMeng这个值,当我们让计算机输出xiaomeng时,在计算机中,xiaomeng这个变量实际上指向的是值为XiaoMeng的内存空间。就像对Python快乐学习班的同学说“集合号”,Python快乐学习班的同学们就知道那指的是他们乘坐的大巴。
在使用变量前需要对其赋值。没有值的变量是没有意义的,编译器也不会编译通过。这就如你碰见一个人就对他说“集合号”,别人肯定会以为你是疯子。
例如,定义一个变量为abc,不赋任何值,输入及结果如下:
>>> abc Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'abc' is not defined
输出结果解释:提示我们名称错误,名称abc没有定义。
同一个变量可以反复赋值,而且可以是不同类型的变量,输入如下:
>>> a = 123 >>> a 123 >>> a = 'ABC' >>> print(a) ABC
这种变量本身类型不固定的语言称为动态语言,与动态语言对应的是静态语言。静态语言在定义变量时必须指定变量类型,对静态语言赋值时,赋值的类型与指定的类型不匹配就会报错。和静态语言相比,动态语言更灵活。
这里提到变量类型的概念,在2.2节提到Python 3中有6种标准对象类型,那么,对于定义的一个变量,怎么知道它的类型是什么?
在Python中,提供了一个内置的type函数帮助识别一个变量的类型,如在交互模式下输入:
>>> type('Hello,world!') <class 'str'>
这里的<class 'str'>指的是Hello这个变量值的类型是str(字符串)类型的。
按同样方式,可以测试50这个值的类型是什么。在交互模式下输入:
>>> type(50) <class 'int'>
计算机反馈的结果类型是整型(int)。再继续测试5.0的类型是什么:
>>> type(5.0) <class 'float'>
计算机反馈的结果类型是浮点型(float)。再继续测试test type的类型是什么:
>>> a = 'test type' >>> type(a) <class 'str'>
计算机反馈的结果类型是字符串类型(str)。
只要是用双引号或单引号括起来的值,都属于字符串。在交互模式下输入:
>>> type('test single quotes') <class 'str'> >>> type("test double quote") <class 'str'> >>> type("100") <class 'str'> >>> type("3.0") <class 'str'> >>> b = '3' >>> type(b) <class 'str'> >>> b = '100' >>> type(b) <class 'str'> >>> c = '3.0' >>> type(c) <class 'str'>
计算机反馈的结果类型都是字符串类型(str)。
注意不要把赋值语句的等号等同于数学中的等号。比如对于下面的两行代码:
a = 100 a = a + 200
这里同学们可能会有疑问,a=a+200是什么等式?这个从以前的学习经验来看是不成立的,在计算机里面怎么就成立了。这里首先要声明,计算机不是人脑,在很多事情的处理上,计算机并不遵循我们眼睛看到的那种规则,计算机有计算机的思维逻辑。
在编程语言中,a=a+200的计算规则是:赋值语句先计算右侧的表达式a+200,得到结果300,再将结果值300赋给变量a。由于a之前的值是100,重新赋值后,a的值变成300。我们通过交互模式做验证,输入如下:
>>> a = 100 >>> a = a + 200 >>> print(a) 300
由输出结果看到,所得结果和前面推理结果一致。
理解变量在计算机内存中的表示也非常重要。在交互模式下输入:
>>> a = '123'
这时,Python解释器做了两件事情:
(1)在内存中开辟一块存储空间,这个存储空间中存放'123'这三个字母对应的字符串。
(2)在内存中创建了一个名为a的变量,并把它指向'123'字符串对应的内存空间。
也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据,例如下面的代码:
>>> a = '123' >>> b = a >>> a = '456' >>> print(b)
最后一行打印出变量b的内容到底是'123'还是'456'呢?如果从数学逻辑推理,得到的结果应该是b和a相同,都是'456',但是实际上,继续往下走,会看到交互模式下打印出的b的值是'123'。
当然,这里我们不急于问为什么,先一行一行执行代码,看看到底是怎么回事。
首先执行a='123',解释器在内存中开辟一块空间,存放字符串'123',并创建变量a,把a指向'123',如图2-3所示。
接着执行b=a,解释器创建了变量b,并把b也指向字符串'123',如图2-4所示,此时a和b都指向了字符串'123'。
再接着执行a = '456',解释器在内存中继续开辟一块空间,开辟的新空间用于存放字符串'456',a的指向更改为字符串'456',b的指向不变,如图2-5所示。
图2-3 a指向'123'
图2-4 a、b指向'123'
图2-5 a指向'456',b不变
最后执行print(b),输出变量b的结果,由图2-5可见,变量b指向的是字符串'123',所以print(b)得到的结果是123。
2.3.2 变量名称
在程序编写时,选择有意义的名称为变量名是一个非常好的习惯,这不但便于以此标记变量的用途,还可以在有多个变量时,易于区分各个变量。就如我们每个人,都被取了一个不那么普通的名字,就是为了方便别人记忆或识别。
在Python中,变量名是由数字或字符组成的任意长度的字符串,且必须以字母开头。使用大写字母是合法的,在命名变量时,为避免变量使用过程中出现一些如拼写上的低级错误,建议变量名中的字母都用小写,因为Python是严格区分大小写的。
举个例子来说,若用Name和name作为变量名,那Name和name就是两个不同的变量。在交互模式下输入如下:
>>> name = 'study python is happy' >>> Name = 'I agree with you' >>> print(name) study python is happy >>> print(Name) I agree with you
在Python中,一般用下画线“_”连接多个词组。Python变量的标准命名规则使用的不是驼峰命名规则。所谓驼峰命名规则,就是一个变量名由多个单词组成时,除第一个单词的首字母小写外,其余单词的首字母都大写。如happy_study, just_do_it就是Python中的标准变量命名方式,如果写成驼峰命名方式,则对应形式如:happyStudy,justDoIt。在交互模式输入Python标准变量命名方式如下:
>>> happy_study = 'stay hungry stay foolish' >>> print(happy_study) stay hungry stay foolish
在Python的命名规则中,变量名不能以数字开头,给变量取名时,若变量的命名不符合Python的命名规则,解释器就会显示语法错误。在交互模式下输入:
该示例提示语法错误,错误信息为无效的语法,错误原因为2wrongtest这个变量不是以字母开头的。再在交互模式下输入:
>>> xiaoming@me = 'surprised' File "<stdin>", line 1 SyntaxError: can't assign to operator
该示例提示语法错误,错误信息为不能做指定操作,错误原因是变量名xiaoming@me中包含了一个非法字符“@”。
Python不允许使用Python内部的关键字作为变量名,在交互模式下输入:
>>> and='use and as variable name' SyntaxError: invalid syntax
and是Python内部的一个关键字,因此出现错误。其实读者若仔细观察,在交互模式下输入and时,and这个变量的字体会变成淡红色,而正常变量的字体是黑色的,这是因为在交互模式下定义变量时,系统会自动校验变量是否是Python的关键字。
2.3.3 Python关键字
所谓关键字,是一门编程语言中预先保留的标识符,每个关键字都有特殊的含义。编程语言众多,但每种语言都有相应的关键字,Python也不例外。
在Python中,自带了一个keyword模块(模块的概念在后续章节会介绍),用于检测关键字。可以通过Python的交互模式做如下操作获取关键字列表:
>>> import keyword >>> keyword.kwlist ['False', 'None', 'True', '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']
由上面的输出结果可以看到,在Python 3.9中共有35个关键字,这些关键字都不能作为变量名来使用。整理成更直观的形式如下:
False None True and as assert break class continue def del elif else except finally for from global if import in nonlocal lambda is not or pass raise return try while with yield async await
注意
Python是一种动态语言,根据时间在不断变化,关键字列表将来有可能会更改。所以读者在使用Python时,若不确定某个变量名是否为Python的关键字,就可以通过使用keyword模块进行查看及校对。