细说Python编程:从入门到科学计算
上QQ阅读APP看书,第一时间看更新

2.6 数据类型

数据类型主要有整数型、浮点型、复数型、字节型、布尔型、字符串型6种,开发人员应该牢固掌握这些数据类型,只有这样才能减少在编写程序时犯的错误。

2.6.1 整数型

整数型(int)数据就是没有小数部分的数字,Python中的整数包括正整数、0和负整数,不同于强类型的编程语言,它的整数不分类型,或者说它只有一种类型的整数。Python整数的取值范围是无限的,无论多大或者多小的数字,Python都能轻松处理。当所用数值超过计算机自身的计算能力时,Python会自动转用高精度计算(大数计算)。

提示

强类型的编程语言会提供多种整数类型,每种类型的长度都不同,能容纳的整数的大小也不同,开发者要根据实际数字的大小选用不同的类型。例如C语言提供了short、int、long、long long 4种类型的整数,它们的长度依次递增,初学者在选择整数类型时往往比较迷惑。

【例2-18】 整数类型应用示例。

输入如下代码:

     # 将21赋值给w
     w = 21
     print(w)
     print(type(w))
     # 给y赋一个很大的值
     y = 9999999999999999
     print(y)
     print(type(y))
     # 给z赋一个很小的值
     z = -76543399988777779
     print(z)
     print(type(z))

运行结果如下:

     21
     <class 'int'>
     9999999999999999
     <class 'int'>
     -76543399988777779
     <class 'int'>

y是一个极大的数字,z是一个很小的数字,Python都能正确输出,不会发生溢出,这说明Python对整数的处理能力非常强大。无论对于多大或者多小的整数,Python只用一种类型存储,就是int。

在Python中,可以使用多种进制来表示整数。

(1)十进制。平时常见的整数就是十进制形式,它由0~9共10个数字排列组合而成。使用十进制形式的整数不能以0作为开头,除非这个数值本身就是0。

(2)二进制。由0和1两个数字组成,书写时以0b或0B开头。例如,101对应的十进制数是5。

(3)八进制。八进制整数由0~7共8个数字组成,以0o或0O开头。注意,第一个是数字0,第二个是大写或小写的字母O。

(4)十六进制。由0~9共10个数字以及A~F(或a~f)6个字母组成,书写时以0x或0X开头。

【例2-19】 不同进制数据Python代码应用示例。

尝试输入如下代码:

     #二进制
     bin1 = 0b101
     print('bin1Value: ', bin1)
     bin2 = 0B110
     print('bin2Value: ', bin2)
     #八进制
     oct1 = 0o26
     print('oct1Value: ', oct1)
     oct2 = 0O41
     print('oct2Value: ', oct2)
     #十六进制
     hex1 = 0x45
     hex2 = 0x4Af
     print("hex1Value: ", hex1)
     print("hex2Value: ", hex2)

运行结果如下:

     bin1Value:  5
     bin2Value:  6
     oct1Value:  22
     oct2Value:  33
     hex1Value:  69
     hex2Value:  1199

为了提高数字的可读性,Python 3.x允许使用下画线“_”作为数字(包括整数和小数)的分隔符。通常每隔3个数字添加一个下画线,类似于英文数字中的逗号。下画线不会影响数字本身的值。

【例2-20】 数字分隔符应用示例。

输入如下代码:

     pi = 3.141_159_265_3
     c = 299_792_458
     print('圆周率 = {}'.format(pi))
     print('光速 = {} m/s'.format(c))

运行结果如下:

     圆周率 = 3.1411592653
     光速 = 299792458 m/s

2.6.2 浮点型

在编程语言中,小数通常以浮点数(float)的形式存储。浮点数和定点数是相对的:小数在存储过程中,如果小数点发生移动,就称为浮点数;如果小数点不动,就称为定点数。

Python中的小数有两种书写形式:aEn或aen。中间的字母e大小写都可以,a为尾数部分,是一个十进制数;n为指数部分,是一个十进制整数;E或e是固定的字符,用于分割尾数部分和指数部分。整个表达式等价于a乘以10的n次方。

注意

只要写成指数形式,就表示小数,即使它的最终值看起来像一个整数。例如14E3等价于14000,但14E3是一个小数。

提示

Python只有float一种小数类型。C语言有float和double两种小数类型,float能容纳的小数范围比较小,double能容纳的小数范围比较大。

【例2-21】 浮点类型应用示例。

输入如下代码:

     a = 25.5
     print("a : ", a)
     print("Type a : ", type(a))
     b = 0.6789123456
     print("b : ", b)
     print("Type b : ", type(b))
     c = 0.00000000000000000000000957
     print("c : ", c)
     print("Type c: ", type(c))
     d = 987654321123456789.789
     print("d : ", d)
     print("Type d : ", type(d))
     e = 34e5
     print("e: ", e)
     print("Type e : ", type(e))

运行结果如下:

     a :  25.5
     Type a :  <class 'float'>
     b :  0.6789123456
     Type b :  <class 'float'>
     c :  9.57e-24
     Type c:  <class 'float'>
     d :  9.876543211234568e+17
     Type d :  <class 'float'>
     e:  3400000.0
     Type e :  <class 'float'>

2.6.3 复数型

复数(complex)是Python的内置类型,直接书写即可。换句话说,Python语言本身就支持复数,而不依赖于标准库或者第三方库。复数由实部(real)和虚部(imag)构成,在Python中,复数的虚部以j或者J作为后缀,具体格式为:a + bj。

【例2-22】 复数类型应用示例。

输入如下代码:

     # 内置函数生成复数
     com1 = complex(12, 102)
     print(com1)
     # 定义生成复数
     com2 = 12 + 102j
     print(com2)
     # 复数计算
     print('com1 + com2 = {}'.format(com1 + com2))
     print('com1 * com2 = {}'.format(com1 * com2))

运行结果如下:

     (12+102j)
     (12+102j)
     com1 + com2 = (24+204j)
     com1 * com2 = (-10260+2448j)

2.6.4 字节型

bytes只负责以字节序列的形式(二进制形式)存储数据,至于这些数据到底表示什么内容(字符串、数字、图片、音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),bytes可以恢复成字符串;反之亦然,字符串也可以转换成bytes。

bytes是Python 3.x新增的类型。bytes只是简单地记录内存中的原始数据,至于如何使用这些数据,bytes并不在意,bytes并不约束使用方式。bytes类型的数据非常适合在互联网上传输,可以用于网络通信编程;bytes也可以用来存储图片、音频、视频等二进制格式的文件。

字符串和bytes存在着千丝万缕的联系,可以通过字符串来创建bytes对象,或者说将字符串转换成bytes对象。有以下3种方法可以实现:

(1)如果字符串的内容都是ASCII字符,那么直接为字符串添加b前缀就可以转换成bytes。

(2)bytes是一个类,调用它的构造方法,也就是bytes(),可以将字符串按照指定的字符集转换成bytes;如果不指定字符集,那么默认采用UTF-8。

(3)字符串本身有一个encode()方法,该方法专门用来将字符串按照指定的字符集转换成对应的字节串;如果不指定字符集,那么默认采用UTF-8。

【例2-23】 使用不同方式创建bytes对象示例。

输入如下代码:

     #通过构造函数创建空 bytes
     b1 = bytes()
     #通过空字符串创建空 bytes
     b2 = b''
     #通过b前缀将字符串转换成 bytes
     b3 = b'I love python/'
     print("b3: ", b3)
     print(b3[3])
     print(b3[7:22])
     #为 bytes()方法指定字符集
     b4 = bytes('大家好', encoding='UTF-8')
     print("b4: ", b4)
     #通过 encode()方法将字符串转换成 bytes
     b5 = "大家好".encode('UTF-8')
     print("b5: ", b5)

运行结果如下:

     #通过构造函数创建空 bytes
     b1 = bytes()
     #通过空字符串创建空 bytes
     b2 = b''
     #通过b前缀将字符串转换成 bytes
     b3 = b'I love python/'
     print("b3: ", b3)
     print(b3[3])
     print(b3[7:22])
     #为bytes()方法指定字符集
     b4 = bytes('大家好', encoding='UTF-8')
     print("b4: ", b4)
     #通过encode()方法将字符串转换成 bytes
     b5 = "大家好".encode('UTF-8')
     print("b5: ", b5)

从运行结果可以发现,对于非ASCII字符,print输出的是它的字符编码值(十六进制形式),而不是字符本身。非ASCII字符一般占用2字节以上的内存,而bytes是按照单字节来处理数据的,所以不能一次处理多字节。

2.6.5 布尔型

类似于其他编程语言,Python提供了布尔(bool)类型来表示True或False,比如比较算式5>3,在程序世界称为真,Python使用True来代表;再比如比较算式4>20,在程序世界称为假,Python使用False来代表。True和False是Python中的关键字,当作为Python代码输入时,一定要注意字母的大小写,否则解释器会报错。

值得一提的是,布尔类型可以被作为整数对待,即True相当于整数值1,False相当于整数值0。

【例2-24】 布尔类型运算示例。

输入如下代码:

     a = False + 10
     b = True + 10
     print('a = {}'.format(a))
     print('b = {}'.format(b))

运行结果如下:

     a = 10
     b = 11

这里只是说明在Python中布尔类型可以这么使用,但不建议这么使用。

总的来说,布尔类型就是用于代表某个事情的真或假,如果这个事情是正确的,用True(或1)表示;如果这个事情是错误的,用False(或0)表示。

布尔类型在循环和判断语句中将大显身手,请看下面的例子。

【例2-25】 布尔类型真假示例。

输入如下代码:

     print('me' == 'you')
     print('100' == 100)
     print(2 < 1)
     print(4 > 2)
     print('me' != 'you')

运行结果如下:

     False
     False
     False
     True
     True

2.6.6 字符串型

所谓字符串,就是由零个或多个字符组成的有限序列,若干个字符的集合就是一个字符串(string)。Python中的字符串必须由双引号""或者单引号''包围,具体格式如下:

     "字符串内容"
     '字符串内容'

字符串的内容可以包含字母、标点、特殊符号、中文、韩文等全世界的所有文字。

Python字符串中的双引号和单引号没有任何区别,而有些编程语言的双引号字符串可以解析变量。以下字符串都是符合Python语法的字符串:

     '我爱Python'
     'www.hao123.com'
     'love1314'
     '3.141592653'

上面介绍了Python字符串的定义和构成,下面对Python字符串中的一些常见问题和用法进行讲解。

1.字符串中的引号

当字符串内容中出现引号时,需要进行特殊处理,否则Python会解析出错,譬如下面的一行代码:

     'I'm a good person!'

由于上面的字符串中包含单引号,此时Python会将字符串中的单引号与第一个单引号配对,这样就会把'I'当成字符串,而后面的m a great person!就变成了多余的内容,从而导致语法错误。对于这种情况,有以下两种处理方案:

1)使用不同的引号包围字符串

如果字符串内容中出现了单引号,那么可以使用双引号包围字符串,反之亦然。譬如以下代码:

2)对引号进行转义

在引号前面添加反斜杠“\”就可以对引号进行转义,让Python把它作为普通文本对待,譬如以下代码:

     str1 = 'I\'m a good person!'
     str2 = "引文双引号是\",中文双引号是""
     print(str1)
     print(str2)

以上两种处理方法运行结果相同,如下所示:

     I'm a good person!
     引文双引号是",中文双引号是“。

2.字符串的换行

Python不是格式自由的语言,它对程序的换行、缩进都有严格的语法要求。要想换行书写一个比较长的字符串,必须在行尾添加反斜杠“\”。

【例2-26】 字符串转换应用示例。

输入如下代码:

运行结果如下:

     I love Python.  I Love Coding.  I Love Monday.

可以看出“\”对一行长代码进行了换行显示。

换行在之前简单介绍过,这里再使用字符串进行代码实践,希望读者对这种用法能有自己的理解,熟练掌握。

3.长字符串

所谓长字符串,就是可以直接换行(不用加反斜杠“\”)书写的字符串。Python长字符串由3个双引号"""或者3个单引号'''包围,语法格式如下:

     """长字符串内容"""
     '''长字符串内容'''

在长字符串中放置单引号或者双引号不会导致解析错误。如果长字符串没有赋值给任何变量,那么这个长字符串就不会起任何作用,和一段普通的文本无异,相当于被注释掉了。

当程序中有大段文本内容需要定义成字符串时,优先推荐使用长字符串形式,因为这种形式非常强大,可以在字符串中放置任何内容,包括单引号和双引号。

【例2-27】 长字符串应用示例。

输入如下代码:

运行结果如下:

     黄山境内分为温泉、云谷、玉屏、北海、松谷、钓桥、浮溪、洋湖、福固9个管理区,有千米以上高峰88座,
     黄山境内有大量的文化遗存,如古蹬道、古楹联、古桥、古亭、古寺、古塔等。
     另有现存摩崖石刻300余处。

长字符串中的换行、空格、缩进等空白符都会原样输出,所以以上代码的输出就是“long_str”这个长字符串原有的格式。

4.Python原始字符串

Python字符串中的反斜杠“\”有着特殊的作用,就是转义字符。转义字符有时会带来一些麻烦,例如要表示一个包含Windows路径D:\Program Files\Python 3.10\python.exe的字符串,在Python程序中不能直接这样输入,无论是普通字符串还是长字符串。

因为“\”的特殊性,需要对字符串中的每个“\”都进行转义,也就是写成D:\\Program Files\\Python 3.10\\python.exe这种形式才行。这种写法需要特别谨慎,稍有疏忽就会出错。为了解决转义字符的问题,Python支持原始字符串。在原始字符串中,“\”不会被当作转义字符,所有的内容都保持“原汁原味”的样子。

在普通字符串或者长字符串的开头加上r前缀,就变成了原始字符串,具体格式如下:

     str1 = r'原始字符串内容'
     str2 = r"""原始字符串内容"""

以刚才的Windows环境路径为例进行代码实战。

【例2-28】 Windows环境路径应用示例。

输入如下代码:

     ori_str = r'D:\Program Files\Python 3.10\python.exe'
     print(ori_str)

运行结果如下:

     D:\Program Files\Python 3.10\python.exe

如果普通格式的原始字符串中出现引号,程序同样需要对引号进行转义,否则Python照样无法对字符串的引号精确配对;但是和普通字符串不同的是,此时用于转义的反斜杠会变成字符串内容的一部分。

注意

Python原始字符串中的反斜杠仍然会对引号进行转义,因此原始字符串的结尾处不能是反斜杠,否则字符串结尾处的引号会被转义,导致字符串不能正确结束。