数据类型
计算机能处理的东西,远比我们想象的要多。除了各种数值计算,文本、图片、音频、视频、网页…这些都能处理。
不同的数据需要用不同的方式来存储和操作,这就是数据类型的由来。Python 里直接能用的基本数据类型有这么几种:
整数
Python 处理整数没有大小限制,正数负数都行。写法跟数学里一样:1、100、-8080、0 这些。
计算机用的是二进制,有时候十六进制会更方便。十六进制用 0x 开头,后面跟 0-9 和 a-f,比如:0xff00、0xa5b4c3d2。
遇到很大的数,比如 10000000000,光数零就数不清了。Python 允许用下划线分隔,写成 10_000_000_000 看着就清楚多了。十六进制也一样,可以写成 0xa1b2_c3d4。
浮点数
浮点数就是小数。为什么叫"浮点"?因为用科学记数法表示的时候,小数点的位置是可以移动的。1.23×10⁹ 和 12.3×10⁸ 其实是同一个数。
普通写法就是数学里那样:1.23、3.14、-9.01。但特别大或特别小的数,就得用科学记数法了。把 10 换成 e:1.23×10⁹ 写成 1.23e9 或 12.3e8,0.000012 写成 1.2e-5。
整数和浮点数在计算机内部的存储方式不一样。整数运算永远精确(包括除法!),浮点数运算可能会有误差,毕竟小数点后面的位数是有限的。
字符串
字符串就是用单引号 ' 或双引号 " 括起来的文本,比如 'abc'、"xyz"。引号本身只是标记,不算字符串的一部分,所以 'abc' 里只有 a、b、c 三个字符。
如果字符串里本身就有单引号,可以用双引号括起来:"I'm OK" 包含 I、’、m、空格、O、K 这 6 个字符。
要是单引号双引号都有呢?用转义字符 \ 来标记:
'I\'m \"OK\"!'
实际内容是:
I'm "OK"!
转义字符 \ 能标记很多特殊字符:\n 表示换行,\t 表示制表符,\\ 表示反斜杠本身。可以在交互式命令行里试试:
>>> print('I\'m ok.')
I'm ok.
>>> print('I\'m learning\nPython.')
I'm learning
Python.
>>> print('\\\n\\')
\
\
如果字符串里转义字符太多,一堆反斜杠看着头疼。Python 提供了 r'' 的写法,表示里面的内容不转义:
>>> print('\\\t\\')
\ \
>>> print(r'\\\t\\')
\\\t\\
字符串内容有很多行的时候,用 \n 写在一起不好看。可以用 '''...''' 的格式:
>>> print('''line1
... line2
... line3''')
line1
line2
line3
在交互式命令行里,输入多行内容时提示符会从 >>> 变成 ...,提示你可以继续输入。提示符只是标记,不是代码的一部分:
┌─────────────────────────────────────────────────────────┐
│Windows PowerShell - □ x │
├─────────────────────────────────────────────────────────┤
│>>> print('''line1 │
│... line2 │
│... line3''') │
│line1 │
│line2 │
│line3 │
│ │
│>>> │
│ │
└─────────────────────────────────────────────────────────┘
输完结束符 ''' 和括号 ) 后,按回车就会执行。
如果写成程序保存为 .py 文件,就是这样:
print('''line1
line2
line3''')
多行字符串前面也可以加 r,自己试试:
print(r'''hello,\n
world''')
布尔值
布尔值只有两个:True 和 False(注意大小写)。可以直接用这两个值,也可以通过比较运算得到:
>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False
布尔值可以用 and、or、not 做运算。
and 是"与"运算,全部为 True 结果才是 True:
>>> True and True
True
>>> True and False
False
>>> False and False
False
>>> 5 > 3 and 3 > 1
True
or 是"或"运算,只要有一个 True 结果就是 True:
>>> True or True
True
>>> True or False
True
>>> False or False
False
>>> 5 > 3 or 1 > 3
True
not 是"非"运算,把 True 变成 False,False 变成 True:
>>> not True
False
>>> not False
True
>>> not 1 > 2
True
布尔值常用在条件判断里:
if age >= 18:
print('adult')
else:
print('teenager')
空值
空值是 Python 里的一个特殊值,用 None 表示。None 不是 0,零是有意义的数字,None 是"什么都没有"的意思。
Python 还有列表、字典等更多数据类型,也支持自定义类型,后面会讲到。
变量
变量的概念跟初中代数差不多,只是在程序里,变量不光能是数字,还能是任何数据类型。
变量用一个名字来表示,名字必须是英文字母、数字和 _ 的组合,而且不能用数字开头:
a = 1
变量 a 是个整数。
t_007 = 'T007'
变量 t_007 是个字符串。
Answer = True
变量 Answer 是个布尔值。
Python 里的等号 = 是赋值,把数据赋给变量。同一个变量可以反复赋值,类型也能变:
a = 123 # a是整数
print(a)
a = 'ABC' # a变成字符串了
print(a)
这种变量类型不固定的语言叫动态语言。静态语言就不一样了,定义变量时必须指定类型,类型不匹配就报错。比如 Java:
int a = 123; // a是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量
动态语言更灵活,就是这个原因。
别把赋值语句的等号当成数学等号。看这段代码:
x = 10
x = x + 2
从数学角度看,x = x + 2 根本不成立。但在程序里,这是先算右边的 x + 2,得到 12,再赋给变量 x。之前 x 是 10,赋值后就变成 12 了。
理解变量在内存里怎么表示也很重要。写下这行代码:
a = 'ABC'
Python 解释器做了两件事:
- 在内存里创建了字符串
'ABC' - 在内存里创建了变量
a,让它指向'ABC'
也可以把一个变量赋给另一个变量,实际上是让第二个变量指向第一个变量指向的数据。看这段代码:
a = 'ABC'
b = a
a = 'XYZ'
print(b)
最后打印 b,结果是 'ABC' 还是 'XYZ'?从数学角度想,可能会觉得 b 和 a 应该一样,是 'XYZ'。但实际上 b 是 'ABC'。一行行执行代码就明白了:
执行 a = 'ABC',解释器创建了字符串 'ABC' 和变量 a,让 a 指向 'ABC':

执行 b = a,解释器创建了变量 b,让 b 指向 a 指向的 'ABC':

执行 a = 'XYZ',解释器创建了字符串 'XYZ',把 a 的指向改成 'XYZ',但 b 没变:

所以打印 b 当然是 'ABC'。
常量
常量就是不能改变的变量。比如数学常数 π 就是常量。Python 里通常用全大写的变量名表示常量:
PI = 3.14159265359
但其实 PI 还是变量,Python 没有任何机制阻止你改它。用全大写只是约定俗成的习惯,真要改也没人拦得住。
说到除法,Python 有两种。一种是 /:
>>> 10 / 3
3.3333333333333335
/ 的结果是浮点数,哪怕两个整数刚好整除:
>>> 9 / 3
3.0
另一种是 //,叫地板除,结果是整数:
>>> 10 // 3
3
没错,// 的结果永远是整数,哪怕除不尽。想要浮点数结果,用 / 就行。
因为 // 只取整数部分,Python 还提供了取余运算 %:
>>> 10 % 3
1
不管是 // 除法还是取余,结果都是整数,所以整数运算永远精确。
练习
打印出下面这些变量的值:
n = 123
f = 456.789
s1 = 'Hello, world'
s2 = 'Hello, \'Adam\''
s3 = r'Hello, "Bart"'
s4 = r'''Hello,
Bob!'''
print(???)
小结
Python 支持多种数据类型。在计算机内部,所有数据都可以看成"对象",变量就是指向这些对象的标记。给变量赋值,就是把数据和变量关联起来。
x = y 这个赋值操作,是让 x 指向 y 指向的对象。之后给 y 赋其他值,不会影响 x 的指向。
Python 的整数没有大小限制,但有些语言(比如 Java)会根据存储长度限制整数范围,32 位整数的范围是 -2147483648 到 2147483647。
Python 的浮点数也没有大小限制,但超出一定范围会直接显示为 inf(无限大)。