1.2 语法规则和基本数据类型
1.2.1 Python语法规则
1.Python标识符
在Python语言中,变量名、函数名、对象名等都是通过标识符来命名的。标识符第一个字符必须是字母表中字母或下划线“_”,标识符的其他部分由字母、数字和下划线组成。Python中的标识符是区分大小写的。在Python 3.X中,非ASCII标识符也是允许的,例如:“data_人数=100”中的“data_人数”为含汉字的标识符。
标识符的命名规则解释如下:
1)标识符是由字符(A~Z和a~z)、下划线和数字组成,但第一个字符不能是数字。
2)标识符不能和Python中的保留字相同。
保留字即关键字,保留字不能用作常量或变量,也不能用作任何其他标识符名称。
Python的标准库提供了一个keyword module,可以输出当前版本的所有关键字,命令和输出结果如下:
所有保留字见表1-1。
表1-1 Python保留字一览表
(续)
由于Python是严格区分大小写的,保留字也不例外。所以,if是保留字,但IF就不是保留字。在实际开发中,如果使用Python中的保留字作为标识符,则解释器会提示“invalid syntax”的错误信息。
3)标识符中不能包含空格、@、%以及$等特殊字符。
例如,UserID、name、mode12、user_age等标识符是合法的。
但以下命名的标识符不合法:
4)标识符中的字母是严格区分大小写的,即使两个同样的单词,如果大小写不一样,其代表的意义也是完全不同的。
比如说,下面这3个变量,它们彼此之间是相互独立的个体。
5)以下划线开头的标识符有特殊含义,例如:
以单下划线开头的标识符(如_width),表示不能直接访问的类属性,其无法通过from…import*的方式导入;
以双下划线开头的标识符(如__add)表示类的私有成员;
以双下划线作为开头和结尾的标识符(如__init__),是专用标识符。
因此,除非特定场景需要,应避免使用以下划线开头的标识符。
2.缩进和冒号
和其他程序设计语言(如Java、C语言)采用大括号“{}”分隔代码块不同,Python采用代码缩进和冒号(:)来区分代码块之间的层次。对于类定义、函数定义、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始,而缩进的结束则表示此代码块的结束。
Python中可以使用空格或者<Tab>键实现对代码的缩进,但无论是使用空格,还是使用<Tab>键,通常情况下都是采用4个空格长度作为一个缩进量。
Python对代码的缩进要求非常严格,同一个级别代码块的缩进量必须一样,否则解释器会报SyntaxError异常错误。
例如,对代码做错误改动,如图1-11所示,将位于同一作用域中的两行代码,它们的缩进量分别设置为4个空格和3个空格,可以看到,当手动修改了各自的缩进量后,这会导致出现SyntaxError异常错误。
图1-11 缩进规则不符导致的SyntaxError异常错误
在IDLE中,默认是以4个空格作为代码的基本缩进单位。不过,这个值是可以手动改变的,可以通过选择“Options”菜单中的“Configure IDLE”命令进行修改。
3.Python引号
Python中使用单引号(')、双引号(")、三引号('"或""")来表示字符串,引号的开始与结束必须是相同种类的引号。其中三引号可以由多行组成,是编写多行文本的快捷语法。使用示例如下:
三引号常用于文档字符串,在文件的特定地点,被当作注释。
4.Python注释
注释(Comments)是用来向用户提示或解释某些代码的作用和功能,它可以出现在代码中的任何位置。Python解释器在执行代码时会忽略注释,不做任何处理。注释的最大作用是提高程序的可读性,还可以用来临时移除无用的代码。一般情况下,合理的代码注释应该占源代码的1/3左右。
Python支持两种类型的注释,分别是单行注释和多行注释。
(1)单行注释
Python使用井号(#)作为单行注释的符号,语法格式为:
从#标注开始,直到这行结束为止的所有内容都是注释。
【例1-2】说明多行代码的功能时一般将注释放在代码的最上面一行。
运算结果:
【例1-3】说明单行代码的功能时一般将注释放在代码的右侧。
运算结果:
(2)多行注释
多行注释指的是一次性注释程序中多行的内容(包含一行)。Python使用三个连续的单引号'''或者三个连续的双引号"""注释多行内容。
不管是多行注释还是单行注释,当注释符作为字符串的一部分出现时,就不能再将它们视为注释标记,而应该看作正常代码的一部分。
【例1-4】注释符作为字符串的一部分。
运算结果:
本例中,第1行和第2行代码,Python没有将这里的三个引号看作是多行注释,而是将它们看作字符串的开始和结束标志;对于第3行代码,Python也没有将#看作单行注释,而是将它看作字符串的一部分。
1.2.2 数据类型概述
Python中主要的内置数据类型有:
1)数值numeric:包括int(整型)、float(浮点数)、bool(布尔型)、complex(复数型)等。
2)序列sequence:包括list(列表)、tuple(元组)、range(范围)、str(字符串)、bytes(字节串)。
3)映射mappings,主要类型为dict(字典)。
4)集合set。
5)类class。
6)实例instance。
7)例外exception。
1.2.3 变量与常量
1.变量的赋值
任何编程语言都需要处理数据,比如数字、字符、字符串等,用户可以直接使用数据,也可以将数据保存到变量中,方便以后使用。变量(Variable)可以看成一个小箱子,专门用来“盛装”程序中的数据。每个变量都拥有独一无二的名字,通过变量的名字就能找到变量中的数据。从底层看,程序中的数据最终都要放到内存(内存条)中,变量其实就是这块内存的名字。图1-12所示是变量age的示意。
图1-12 变量age的示意
在编程语言中,将数据放入变量的过程称为赋值(Assignment)。Python使用等号“=”作为赋值运算符,具体语法格式为:
其中,name表示变量名;value表示值,也就是要存储的数据。
例如,图1-12中的语句“age=20”就是将整数20赋值给变量age。
在程序的其他地方,age就代表整数20,使用age也就是使用20。
【例1-5】变量赋值实例一。
变量的值不是一成不变的,它可以随时被修改,只要重新赋值即可。另外用户也不用关心数据的类型,可以将不同类型的数据赋值给同一个变量。
【例1-6】变量赋值实例二。
运算结果:
从上述例子中可以看到,除了赋值单个数据,用户也可以将表达式的运行结果赋值给变量。
和变量相对应的是常量(Constant),它们都是用来“盛装”数据的小箱子,不同的是,变量保存的数据可以被多次修改,而常量一旦保存某个数据之后就不能修改了。
2.单下划线、双下划线开始的特殊变量及特殊方法专用标识
Python用单下划线和双下划线作为变量前缀和后缀指定特殊变量。
(1)_xxx变量名
_xxx被看作是“私有的”变量,在模块或类外不可以使用。当变量是私有的时候,用_xxx来表示变量是很好的习惯。_xxx变量是不能用“from module import*”导入的。在类中以“单下划线”开始的成员变量或类属性称为保护变量,意思是只有类对象和子类对象自己能访问到这些变量。
(2)__xxx类中的私有变量名
以“双下划线”开始的变量是私有成员变量,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)__xxx__特殊方法专用标识
以双下划线开头和结尾的代表Python里特殊方法专用标识,如__init__(self,...)代表类的构造函数。这样的系统特殊方法还有许多,如:
__new__(cls[,...])、__del__(self)、__str__(self)、__lt__(self,other)、__getitem__(self,key)、__len__(self)、__repr__(s)、_cmp__(s,o)、__call__(self,*args)等。
因此要注意避免用下划线作为一般变量名的开始。
3.常量、内置常量
变量是变化的量,常量则是不变的量。Python中没有使用语法强制定义常量,有个例外,就是Python有少数的常量存在于内置命名空间中的内置常量,它们是
(1)False
bool类型的假值。给False赋值是非法的并且会引发SyntaxError异常提示。
(2)True
bool类型的真值。给True赋值是非法的并且会引发SyntaxError异常提示。
(3)None
NoneType类型的唯一值。None经常用于表示缺少值,当因为默认参数未传递给函数时。给None赋值是非法的并且会引发SyntaxError异常提示。
(4)NotImplemented
NotImplemented是个特殊值,它能被二元特殊方法返回(比如__eq__()、lt()、add()、rsub()等),表明某个类型没有像其他类型那样实现这些操作。同样,它也可以被原地处理(in place)的二元特殊方法返回(比如__imul__()、iand()等)。还有,它的实际值为True。
(5)Ellipsis
Ellipsis是个特殊值,含义即“省略”,与省略号文字字面“...”相同。
(6)__debug__
如果Python没有以-O选项启动,则__debug__常量为真值。
(7)quit(code=None)、exit(code=None)
当打印此对象时,会打印出一条消息,例如“Use quit() or Ctrl-D(i.e.EOF) to exit”。当调用此对象时,将使用指定的退出代码来引发SystemExit。
(8)copyright、credits
打印或调用的对象分别打印版权或作者的文本。
(9)license
当打印此对象时,会打印出一条消息“Type license() to see the full license text”。当调用此对象时,将以分页形式显示完整的许可证文本(每次显示一屏)。
1.2.4 整数类型
1.整数的赋值
整数就是没有小数部分的数字,Python的整数数据类型包括正整数、0和负整数,取值范围则是无限的,不管多大或者多小的数字构成的整数,Python都能轻松处理。当所用数值超过计算机自身的计算能力时,Python会自动使用高精度计算。
【例1-7】整数的赋值。
运算结果:
从本例中可以看出,num1是一个看起来非常正常的整数,num2是一个极大的数字,num3则是一个很小的数字,Python都能正确输出这3个变量,不会发生溢出,这说明Python对整数的处理能力非常强大。
2.整数的不同进制
整数可以使用多种进制来表示,常见的有十进制、二进制、八进制和十六进制等形式。
(1)十进制形式
平时常见的整数就是十进制形式,它由0~9共十个数字排列组合而成。需要注意的是,使用十进制形式的整数不能以0作为开头,除非这个数值本身就是0。
(2)二进制形式
由0和1两个数字组成,书写时以0b或0B开头。例如,0b101对应的十进制数是5。
(3)八进制形式
八进制整数由0~7共八个数字组成,以0o或0O开头。注意,第一个符号是数字0,第二个符号是大写或小写的字母o。
(4)十六进制形式
由0~9十个数字以及A~F(或a~f)六个字母组成,书写时以0x或0X开头。
【例1-8】二进制、八进制、十六进制整数的使用。
运算结果:
本例的输出结果都是十进制整数。
3.数字分隔符
为了提高数字的可读性,允许使用下划线“_”作为数字(包括整数和小数)的分隔符。通常每隔三个数字添加一个下划线,类似于英文数字中的逗号。下划线不会影响数字本身的值。
【例1-9】数字分隔符的使用。
运算结果:
1.2.5 小数、浮点数和复数类型
在高级编程语言中,小数通常以浮点数的形式存储。浮点数和定点数是相对的,小数在存储过程中,如果小数点发生移动,就称为浮点数;如果小数点不动,就称为定点数。Python只有一种小数类型,就是浮点数(float)。
Python中的小数有两种书写形式,即十进制形式和指数形式。
(1)十进制形式
平时看到的小数形式都是十进制形式,例如231.5、23.1、0.231。书写小数时必须包含一个小数点,否则会被Python当作整数处理。
(2)指数形式
Python小数的指数形式的写法为
其中,a为尾数部分,是一个十进制数;n为指数部分,是一个十进制整数;E或e是固定的字符,用于分割尾数部分和指数部分。整个表达式等价于a×10n。
指数形式的小数举例:
1.8E4=1.8×104,其中1.8是尾数,4是指数。
2.5E-3=2.5×10-3,其中2.5是尾数,-3是指数。
0.3E4=0.3×104,其中0.3是尾数,4是指数。
只要写成指数形式就是小数,即使它的最终值看起来像一个整数。如12E2等价于1200,但它是一个小数。
【例1-10】小数的应用。
运算结果:
从本例中可以看出,print在输出浮点数时,会根据浮点数的长度和大小适当地舍去一部分数字,或者采用科学计数法。
复数(Complex)是Python的内置类型,直接书写即可,不依赖于标准库或者第三方库。复数由实部(real)和虚部(imag)构成,在Python中,复数的虚部以j或者J作为后缀,具体格式为
其中,a表示实部,b表示虚部。
1.2.6 字符串及其基本操作
字符串(String)就是若干个字符的集合,Python中的字符串必须由双引号""或者单引号''引用,其双引号和单引号没有任何区别,具体格式为:
字符串的内容可以包含字母、标点、特殊符号、中文、日文、韩文等。
下面都是合法的字符串:
1.处理字符串中的引号
当字符串内容中出现引号时,用户需要进行特殊处理,否则Python会解析出错,例如:
由于上面字符串中包含了单引号,此时Python会将字符串中的单引号与第一个单引号配对,这样就会把'I'当成字符串,而后面的m a doctor!'就变成了多余的内容,从而导致语法错误。
对于这种情况,一般有两种处理方案:
(1)对引号进行转义
在引号前面添加反斜杠“\”就可以对引号进行转义,让Python把它作为普通文本对待。
(2)使用不同的引号引用字符串
如果字符串内容中出现了单引号,那么我们可以使用双引号引用字符串,反之亦然。
【例1-11】对引号进行转义和使用不同的引号引用字符串。
运算结果:
2.字符串的换行
Python不是格式自由的语言,它对程序的换行、缩进都有严格的语法要求。要想换行书写一个比较长的字符串,必须在行尾添加反斜杠“\”。Python也支持表达式添加反斜杠“\”的换行。
3.长字符串
Python长字符串由三个双引号"""或者三个单引号'''引用,语法格式如下:
在长字符串中放置单引号或者双引号不会导致解析错误。
4.转义字符
对于ASCII编码来说,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。不过直接使用ASCII码记忆不方便,也不容易理解,所以针对常用的控制字符,Python语言定义了转义字符方式,见表1-2。
表1-2 Python支持的转义字符
(续)
转义字符在书写形式上由多个字符组成,但Python将它们看作是一个整体,表示一个字符。
此外,转义字符以“\0”(是数字0,不是字母o)或者“\x”开头的表示编码值,前者表示跟八进制形式的编码值,后者表示跟十六进制形式的编码值,如\0dd或\xhh等,其中dd表示八进制数字,hh表示十六进制数字。
由于ASCII编码共收录了128个字符,\0和\x后面最多只能跟两位数字,所以八进制形式\0并不能表示所有的ASCII字符,只有十六进制形式\x才能表示所有ASCII字符。
【例1-12】使用八进制、十六进制来显示ASCII码。
运算结果:
从本例中可以看出,字符C、E、G、I、K、M十六进制形式分别是43、45、47、49、4B、4D;字符1、3、5对应的ASCII码八进制形式分别是61、63、65;“\t\t”表示2个<Tab>键位置。
1.2.7 数据类型转换
Python已经为我们提供了多种可实现数据类型转换的函数,见表1-3。需要注意的是,在使用类型转换函数时,提供给它的数据必须是有意义的。
表1-3 常用数据类型转换函数
(续)