5.1. 数据类型和变量

深入学习Python数据类型和变量,包括整数、浮点数、字符串、布尔值等基本数据类型,掌握Python变量的定义和使用方法,了解动态类型语言的特点。

数据类型

计算机能处理的东西,远比我们想象的要多。除了各种数值计算,文本、图片、音频、视频、网页…这些都能处理。

不同的数据需要用不同的方式来存储和操作,这就是数据类型的由来。Python 里直接能用的基本数据类型有这么几种:

整数

Python 处理整数没有大小限制,正数负数都行。写法跟数学里一样:1100-80800 这些。

计算机用的是二进制,有时候十六进制会更方便。十六进制用 0x 开头,后面跟 0-9 和 a-f,比如:0xff000xa5b4c3d2

遇到很大的数,比如 10000000000,光数零就数不清了。Python 允许用下划线分隔,写成 10_000_000_000 看着就清楚多了。十六进制也一样,可以写成 0xa1b2_c3d4

浮点数

浮点数就是小数。为什么叫"浮点"?因为用科学记数法表示的时候,小数点的位置是可以移动的。1.23×10⁹ 和 12.3×10⁸ 其实是同一个数。

普通写法就是数学里那样:1.233.14-9.01。但特别大或特别小的数,就得用科学记数法了。把 10 换成 e:1.23×10⁹ 写成 1.23e912.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''')

布尔值

布尔值只有两个:TrueFalse(注意大小写)。可以直接用这两个值,也可以通过比较运算得到:

>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False

布尔值可以用 andornot 做运算。

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。之前 x10,赋值后就变成 12 了。

理解变量在内存里怎么表示也很重要。写下这行代码:

a = 'ABC'

Python 解释器做了两件事:

  1. 在内存里创建了字符串 'ABC'
  2. 在内存里创建了变量 a,让它指向 'ABC'

也可以把一个变量赋给另一个变量,实际上是让第二个变量指向第一个变量指向的数据。看这段代码:

a = 'ABC'
b = a
a = 'XYZ'
print(b)

最后打印 b,结果是 'ABC' 还是 'XYZ'?从数学角度想,可能会觉得 ba 应该一样,是 '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 位整数的范围是 -21474836482147483647

Python 的浮点数也没有大小限制,但超出一定范围会直接显示为 inf(无限大)。