Skip to content

Python3 数据类型与变量

目录

  • 一、为什么要有数据类型
  • 二、整数 int
  • 三、浮点数 float
  • 四、字符串 str
  • 五、布尔值 bool
  • 六、空值 None
  • 七、变量(核心重点)
  • 八、常量
  • 九、除法与取余
  • 十、动手练习
  • 十一、小结

一、为什么要有数据类型

计算机,顾名思义,最早就是用来做数学计算的机器,所以它理所当然能处理各种数值。但计算机能处理的远不止数值——还能处理文本、图形、音频、视频、网页等五花八门的数据。

不同的数据,需要定义不同的数据类型(Data Type)。就像超市里饮料放冷柜、大米放粮区、电池放收银台旁,分门别类才好管理;程序里的数据也要分类,因为不同类型的数据,存放方式和使用方法都不一样

Python 中能够直接处理的基础数据类型,主要有下面几种:

类型关键字例子一句话说明
整数int1-80没有小数点的数
浮点数float3.141.5e3小数,也叫浮点数
字符串str'abc'"xyz"一串文字
布尔值boolTrueFalse只有"真/假"两种值
空值NoneTypeNone表示"什么都没有"

除此之外,Python 还提供了列表、字典等多种数据类型,以及允许自定义类型,这些会在后续章节展开。

💡 小提示:学习任何编程语言,数据类型都是第一块基石。记住这张表,后面的变量、运算、判断全都建立在它之上。


二、整数 int

2.1 任意大小的整数

Python 可以处理任意大小的整数,正数、负数、零都可以,写法和数学里一模一样:

python
a = 1
b = -8080
c = 0
print(a, b, c)

运行结果:

1 -8080 0

💡 Python 的独特优势:很多语言(比如 Java)的整数是有大小上限的,32 位整数最大只能到 2147483647。而 Python 的整数没有大小限制,只要内存够大,几百位的数字也能直接算。

2.2 用十六进制表示整数

计算机内部使用二进制。有时候用十六进制表示整数会更方便,用 0x 作前缀、0-9a-f 表示:

python
print(0xff00)        # 十六进制,等于十进制的 65280
print(0xa5b4c3d2)    # 一个很大的十六进制数

运行结果:

65280
2778211282

除了十六进制,Python 还支持二进制0b 开头)和八进制0o 开头):

python
print(0b1010)    # 二进制 1010,等于十进制 10
print(0o17)      # 八进制 17,等于十进制 15
print(0x1F)      # 十六进制 1F,等于十进制 31

运行结果:

10
15
31

2.3 用下划线分隔大数

对于很大的数,比如 10000000000,很难一眼数清楚有几个 0。Python 允许在数字中间用 _ 分隔,方便阅读:

python
print(10_000_000_000)    # 和 10000000000 完全一样
print(0xa1b2_c3d4)       # 十六进制也可以加下划线

运行结果:

10000000000
2713871348

💡 _ 只是给人看的"千位分隔符",Python 在计算时会自动忽略它,不影响数值本身。

2.4 整数运算永远是精确的

两个整数做加减乘除,结果永远是精确的,不会出现四舍五入的误差:

python
print(1 + 2)
print(100 - 1)
print(3 * 4)
print(10 // 3)    # 地板除,取整数部分
print(10 % 3)     # 取余数

运行结果:

3
99
12
3
1

⚠️ 关于除法 /// 的区别,是很多人早期最容易搞混的点,我们在第九节单独详细讲。

2.5 整数的常用方法与内置函数

整数虽然只是"一个数",但 Python 为它准备了不少内置函数和方法,能帮你做进制转换、批量统计、位运算等操作。

(1)进制转换:bin / oct / hex

把十进制整数转成二进制、八进制、十六进制的字符串:

python
print(bin(10))     # 二进制,'0b1010'
print(oct(15))     # 八进制,'0o17'
print(hex(31))     # 十六进制,'0x1f'

运行结果:

0b1010
0o17
0x1f

💡 注意:bin()/oct()/hex() 返回的是字符串,且自带前缀(0b/0o/0x)。反过来把字符串转回整数,用 int(s, 进制)

python
print(int('1010', 2))    # 二进制字符串转十进制:10
print(int('17', 8))      # 八进制:15
print(int('1f', 16))     # 十六进制:31

运行结果:

10
15
31

(2)绝对值:abs

python
print(abs(-7))
print(abs(7))

运行结果:

7
7

(3)divmod:一次得到商和余数

divmod(a, b) 返回一个元组 (商, 余数),等价于 (a // b, a % b)

python
print(divmod(10, 3))    # (3, 1)

运行结果:

(3, 1)

(4)pow:幂运算

python
print(pow(2, 10))        # 2 的 10 次方 = 1024
print(pow(2, 10, 1000))  # 2**10 % 1000 = 24(第三个参数是取模)

运行结果:

1024
24

(5)bit_length / bit_count:位操作

python
n = 10
print(n.bit_length())          # 二进制表示需要几位:10 = 0b1010,需要 4 位
print((0b1010).bit_count())    # 二进制里 1 的个数(Python 3.10+)

运行结果:

4
2

(6)max / min / sum:批量统计

python
print(max(1, 5, 3))        # 最大值
print(min(1, 5, 3))        # 最小值
print(sum([1, 2, 3, 4]))   # 求和

运行结果:

5
1
10

(7)to_bytes / from_bytes:整数与字节互转

python
n = 1024
b = n.to_bytes(2, byteorder='big')    # 转成 2 字节,大端序
print(b)                              # b'\x04\x00'
print(int.from_bytes(b, byteorder='big'))  # 转回整数:1024

运行结果:

b'\x04\x00'
1024

(8)as_integer_ratio:转成分数(Python 3.8+)

python
print((10).as_integer_ratio())    # (10, 1)

运行结果:

(10, 1)

(9)is_integer / real / imag / numerator / denominator:数值协议属性

python
n = 42
print(n.is_integer())     # True
print(n.real)             # 42(实部)
print(n.imag)             # 0(虚部)
print(n.numerator)        # 42(分子)
print(n.denominator)      # 1(分母)

运行结果:

True
42
0
42
1

(10)conjugate:共轭复数

python
print((3 + 4j).conjugate())    # (3-4j)
print((42).conjugate())        # 42(整数的共轭是自己)

运行结果:

(3-4j)
42

(11)index:支持切片和索引

python
class MyInt:
    def __index__(self):
        return 5

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[MyInt()])    # 5,等价于 lst[5]

运行结果:

5

💡 小结:整数自身的方法不多,更多是靠内置函数absdivmodpowbinocthexmaxminsum)来操作。to_bytes/from_bytes 在网络编程和二进制文件处理中常用;real/imag/conjugate 是为了兼容复数协议而存在的。


三、浮点数 float

3.1 什么是浮点数

浮点数就是小数。之所以叫"浮点",是因为按科学记数法表示时,小数点位置是"浮动"的。例如 1.23 × 10⁹12.3 × 10⁸ 是完全相等的——小数点位置变了,但值没变。

普通写法:

python
pi = 3.14
price = 9.9
print(pi, price)

运行结果:

3.14 9.9

3.2 科学计数法

对于很大或很小的浮点数,必须用科学计数法表示,把 10 换成字母 e

python
print(1.23e9)     # 1.23 × 10⁹ = 1230000000.0
print(12.3e8)     # 12.3 × 10⁸,和上面相等
print(1.2e-5)     # 1.2 × 10⁻⁵ = 0.000012

运行结果:

1230000000.0
1230000000.0
1.2e-05

3.3 浮点数可能有误差(重要!)

整数运算永远是精确的,但浮点数运算可能会有四舍五入的误差。这是所有计算机的通病,不是 Python 的 bug:

python
print(0.1 + 0.2)

运行结果:

0.30000000000000004

你期望是 0.3,结果却是 0.30000000000000004。原因是浮点数在计算机内部用二进制存储,而 0.10.2 这样的十进制小数无法用二进制精确表示。

⚠️ 怎么应对:涉及钱的精确计算,不要直接用浮点数比大小或相加。可以用整数"以分为单位"存储,或者用 round() 取近似值,进阶时再用 decimal 模块。

python
print(round(0.1 + 0.2, 10) == 0.3)    # True

💡 另一个细节:Python 的浮点数虽然也有范围,但超出一定范围会直接表示为 inf(无穷大),而不是报错:

python
print(1e400)    # 超出范围,显示为 inf

3.4 浮点数的常用方法与内置函数

浮点数除了加减乘除,还有一些专门的方法和配套函数。

(1)round:四舍五入

python
print(round(3.14159, 2))   # 保留 2 位小数:3.14
print(round(3.14159))      # 不传位数,取整:3

运行结果:

3.14
3

(2)is_integer:判断小数部分是否为 0

python
print((4.0).is_integer())    # True
print((4.5).is_integer())    # False

运行结果:

True
False

⚠️ 注意 4.0 要加括号写成 (4.0).is_integer(),否则 4.0.is_integer() 里的 . 会被解析成小数点的一部分,报语法错误。

(3)hex / fromhex:十六进制表示

python
print((1.5).hex())    # '0x1.8000000000000p+0'
print(float.fromhex('0x1.8000000000000p+0'))    # 1.5

运行结果:

0x1.8000000000000p+0
1.5

(4)as_integer_ratio:转成分数

python
print(0.75.as_integer_ratio())    # (3, 4),即 3/4

运行结果:

(3, 4)

(5)math 模块的配套函数

浮点运算经常配合 math 标准库使用:

python
import math

print(math.floor(3.7))     # 向下取整:3
print(math.ceil(3.2))      # 向上取整:4
print(math.trunc(-3.7))    # 向零取整(直接砍掉小数):-3
print(math.pi)             # 圆周率 π
print(math.e)              # 自然常数 e
print(math.sqrt(16))       # 平方根:4.0

运行结果:

3
4
-3
3.141592653589793
2.718281828459045
4.0

(6)real / imag / conjugate:复数协议兼容

python
f = 3.14
print(f.real)           # 3.14(实部)
print(f.imag)           # 0.0(虚部)
print(f.conjugate())    # 3.14(共轭复数,浮点数的共轭是自己)

运行结果:

3.14
0.0
3.14

(7)format:格式化输出

python
f = 3.14159
print(f.__format__('.2f'))    # '3.14'
print(f.__format__('10.2f'))  # '      3.14'(总宽10,保留2位小数)
print(f.__format__('.2e'))    # '3.14e+00'(科学计数法)

运行结果:

3.14
      3.14
3.14e+00

(8)isfinite / isinf / isnan:数值状态判断

python
import math

f = math.inf
print(math.isfinite(f))    # False
print(math.isinf(f))       # True
print(math.isnan(f))       # False

n = float('nan')
print(math.isnan(n))       # True

运行结果:

False
True
False
True

💡 记忆点round 是四舍五入,floor 向下取整,ceil 向上取整,trunc 向零取整。名字很形象:floor(地板)往下、ceil(天花板)往上。is_integerhexas_integer_ratio 是浮点数自身的方法;isfinite/isinf/isnan 需要 math 模块。


四、字符串 str

4.1 用引号包起来的文本

字符串是用单引号 ' 或双引号 " 包起来的任意文本:

python
s1 = 'abc'
s2 = "xyz"
print(s1, s2)

运行结果:

abc xyz

💡 重要理解''"" 本身只是"标记",不是字符串内容的一部分。所以 'abc' 这个字符串只有 abc 这 3 个字符,不含引号。

4.2 字符串里要包含引号怎么办

如果字符串内部本身有 ',就可以用双引号把它包起来:

python
s = "I'm OK"
print(s)

运行结果:

I'm OK

那如果字符串里 '" 都有呢?可以用转义字符 \ 来标识:

python
s = 'I\'m "OK"!'
print(s)

运行结果:

I'm "OK"!

4.3 常用转义字符

转义字符 \ 可以转义很多字符,让它们表示"特殊含义":

转义符含义示例写法实际效果
\n换行'a\nb'a 换行 b
\t制表符(Tab)'a\tb'a b
\\反斜杠本身'\\'\
\'单引号'I\'m'I'm
\"双引号"say \"hi\""say "hi"

print() 打印一下,能更直观地看到转义效果:

python
print('I\'m ok.')
print('I\'m learning\nPython.')
print('\\\n\\')

运行结果:

I'm ok.
I'm learning
Python.
\
\

4.4 原始字符串 r''(不转义)

如果字符串里有很多字符都需要转义,就要写一大堆 \,很麻烦。Python 允许用 r'' 表示"原始字符串"——内部字符默认不转义

python
print('\\\t\\')     # 普通字符串:\t 被转义成制表符
print(r'\\\t\\')    # 原始字符串:原样输出,不转义

运行结果:

\	\
\\\t\\

💡 什么时候用 r'':最典型的就是 Windows 文件路径,比如 r'C:\Users\name'。如果不用 r,就得写成 'C:\\Users\\name',非常啰嗦。

4.5 多行字符串 '''...'''

如果字符串里有很多换行,用 \n 写在一行里很难阅读。Python 允许用 '''...''' 表示多行内容:

python
print('''line1
line2
line3''')

运行结果:

line1
line2
line3

💡 交互式命令行的细节:在 >>> 提示符下输入多行内容时,提示符会从 >>> 变成 ...,表示"接着上一行继续输入"。注意 ... 是提示符,不是代码的一部分。写完结束符 ''' 后回车,才会执行这条语句。

多行字符串 '''...''' 前面也能加 r,让多行内容也不转义:

python
print(r'''hello,\n
world''')

运行结果:

hello,\n
world

💡 三引号的另一用途'''...''' 还常用来写多行注释文档字符串(docstring),本质就是一个"没被使用的字符串"。

4.6 字符串的更多常用方法

字符串是方法最丰富的数据类型。前面讲了拼接、切片、转义,这里再补充一批高频方法(stripsplitreplacefind 等已在《Python3 基本数据类型》中详细介绍,此处不重复)。

(1)大小写转换的补充

python
s = "Hello World"
print(s.swapcase())      # 大小写互换:hELLO wORLD
print(s.capitalize())    # 首字母大写,其余小写:Hello world
print(s.casefold())      # 更彻底的小写(适合忽略大小写比较)

运行结果:

hELLO wORLD
Hello world
hello world

(2)对齐与填充

python
s = "42"
print(s.center(6, '*'))   # 居中,用 * 补齐:**42**
print(s.ljust(6, '-'))    # 左对齐,右侧补 -:42----
print(s.rjust(6, '-'))    # 右对齐,左侧补 -:----42
print(s.zfill(6))         # 左侧补 0:000042

运行结果:

**42**
42----
----42
000042

(3)更多判断方法

python
print("HELLO".isupper())        # 是否全大写
print("hello".islower())        # 是否全小写
print("Hello".istitle())        # 是否每个单词首字母大写
print("123".isdecimal())      # 是否全是十进制数字(含全角)
print("1_000".isidentifier())   # 是否是合法变量名

运行结果:

True
True
True
True
True

(4)反向查找:rfind / rindex

python
s = "hello world hello"
print(s.find("hello"))     # 从左找,第一次出现的位置:0
print(s.rfind("hello"))    # 从右找,最后一次出现的位置:12

运行结果:

0
12

(5)partition:按分隔符一分为三

python
s = "2026-08-27"
print(s.partition("-"))    # ('2026', '-', '08-27')

运行结果:

('2026', '-', '08-27')

(6)splitlines:按换行拆分

python
text = "第一行\n第二行\n第三行"
print(text.splitlines())    # ['第一行', '第二行', '第三行']

运行结果:

['第一行', '第二行', '第三行']

(7)removeprefix / removesuffix(Python 3.9+)

python
s = "prefix_hello"
print(s.removeprefix("prefix_"))       # hello
print("hello.txt".removesuffix(".txt")) # hello

运行结果:

hello
hello

(8)split / rsplit / join:拆分与拼接

python
s = "apple,banana,orange"
print(s.split(","))        # 按逗号拆分:['apple', 'banana', 'orange']
print(s.rsplit(",", 1))    # 从右拆,只拆1次:['apple,banana', 'orange']

parts = ["2026", "08", "27"]
print("-".join(parts))     # 用 - 拼接:'2026-08-27'

运行结果:

['apple', 'banana', 'orange']
['apple,banana', 'orange']
2026-08-27

(9)strip / lstrip / rstrip:去除首尾字符

python
s = "  hello world  "
print(s.strip())       # 去首尾空格:'hello world'
print(s.lstrip())      # 只去左边:'hello world  '
print(s.rstrip())      # 只去右边:'  hello world'
print("  hello  ".strip("h o"))   # 去指定字符:'ello'

运行结果:

hello world
hello world
  hello world
ello

(10)replace:替换

python
s = "hello world hello"
print(s.replace("hello", "hi"))        # 全部替换:'hi world hi'
print(s.replace("hello", "hi", 1))     # 只替换1次:'hi world hello'

运行结果:

hi world hi
hi world hello

(11)startswith / endswith:开头结尾判断

python
s = "hello.py"
print(s.startswith("hello"))    # True
print(s.endswith(".py"))        # True
print(s.endswith((".py", ".txt")))  # True,可传元组

运行结果:

True
True
True

(12)count / index:统计与定位

python
s = "hello world hello"
print(s.count("hello"))     # 出现次数:2
print(s.index("world"))     # 第一次出现位置:6
# print(s.index("xyz"))     # 找不到会报 ValueError

运行结果:

2
6

(13)encode / decode:编码转换

python
s = "你好"
b = s.encode("utf-8")       # 字符串 → bytes
print(b)                    # b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(b.decode("utf-8"))    # bytes → 字符串:'你好'

运行结果:

b'\xe4\xbd\xa0\xe5\xa5\xbd'
你好

(14)format / f-string:格式化输出

python
name = "Alice"
age = 25
print("我叫{},今年{}岁".format(name, age))      # 我叫Alice,今年25岁
print(f"我叫{name},今年{age}岁")                 # 同上(推荐,Python 3.6+)
print(f"{age:03d}")                               # 025(补0到3位)

运行结果:

我叫Alice,今年25岁
我叫Alice,今年25岁
025

(15)maketrans / translate:字符映射替换

python
table = str.maketrans("aeiou", "12345")
s = "hello world"
print(s.translate(table))    # h2ll4 w4rld

运行结果:

h2ll4 w4rld

💡 记忆点:字符串方法都返回新字符串,不会改原字符串(因为字符串不可变)。想保留结果必须接收返回值:s = s.strip(),而不是 s.strip() 后就以为 s 变了。


五、布尔值 bool

5.1 只有 True 和 False

布尔值和布尔代数完全一致,一个布尔值只有 TrueFalse 两种值,要么是 True,要么是 False。可以直接写,也可以通过比较运算得到:

python
print(True)
print(False)
print(3 > 2)     # 比较结果是布尔值
print(3 > 5)

运行结果:

True
False
True
False

⚠️ 注意大小写TrueFalse 首字母必须大写!写 true / false 会报 NameError

5.2 布尔运算:and、or、not

布尔值可以用 andornot 做运算。

and(与运算):只有两边都为 True,结果才是 True

python
print(True and True)      # True
print(True and False)     # False
print(False and False)    # False
print(5 > 3 and 3 > 1)    # True

or(或运算):只要有一边为 True,结果就是 True

python
print(True or True)      # True
print(True or False)     # True
print(False or False)    # False
print(5 > 3 or 1 > 3)    # True

not(非运算):单目运算符,取反:

python
print(not True)      # False
print(not False)     # True
print(not 1 > 2)     # True(1 > 2 是 False,取反后是 True)

5.3 布尔值常用在条件判断里

布尔值最常出现在 if 判断中:

python
age = 20
if age >= 18:
    print('adult')
else:
    print('teenager')

运行结果:

adult

💡 记忆口诀and 是"都真才真",or 是"有真就真",not 是"真假颠倒"。

5.4 布尔值的转换与细节

布尔值自身没多少方法,但有几个实用细节值得记住。

(1)bool():任何值都能判断真假

python
print(bool(0))        # False
print(bool(42))       # True
print(bool(""))       # False
print(bool("hi"))     # True
print(bool([]))       # False
print(bool(None))     # False

运行结果:

False
True
False
True
False
False

💡 真值规则:以下值在判断时会被当作 False——00.0""(空字符串)、[](空列表)、()(空元组)、{}(空字典)、set()(空集合)、None。其余一律当作 True

(2)True / False 本质是 1 和 0

布尔值是 int 的子类,True 相当于 1False 相当于 0

python
print(int(True))      # 1
print(int(False))     # 0
print(True + True)    # 2(因为 True 就是 1)

运行结果:

1
0
2

⚠️ 提醒:虽然 True == 1 成立,但 True1类型不同。判断相等用 ==,判断"是不是同一个对象"用 is,别混用。

(3)bit_length / bit_count:继承自 int 的位操作

python
print(True.bit_length())     # 1(True 就是 1,二进制 1 需要 1 位)
print(False.bit_length())    # 0(False 就是 0)
print(True.bit_count())      # 1(二进制里 1 的个数)

运行结果:

1
0
1

(4)conjugate / real / imag:复数协议兼容

python
print(True.conjugate())    # 1
print(True.real)           # 1
print(True.imag)           # 0

运行结果:

1
1
0

(5)and / or / xor:位运算的魔术方法

python
print(True.__and__(True))     # True  & True  = True
print(True.__or__(False))     # True  | False = True
print(True.__xor__(True))     # True  ^ True  = False

运行结果:

True
True
False

💡 说明:布尔值的方法基本继承自 int,因为 boolint 的子类。日常开发中几乎不会直接调用这些方法,但理解它们有助于明白"布尔值本质上是 0 和 1"这一设计。


六、空值 None

空值是 Python 里一个特殊的值,用 None 表示。

python
x = None
print(x)
print(type(x))

运行结果:

None
<class 'NoneType'>

⚠️ 关键区分None 不能理解为 00 是一个有意义的数字,而 None 是一个特殊的"空值",表示"这里什么都没有"。它和空字符串 ''、空列表 [] 也不是一回事——那些是"有类型但没内容",None 是"根本没有值"。

💡 判断是否为 None:推荐用 is None,而不是 == None

python
data = None
if data is None:
    print("还没有数据")

七、变量(核心重点)

7.1 变量是什么

变量的概念,基本和初中代数里的"方程变量"是一致的。只是程序里的变量更厉害——它不仅可以是数字,还可以是任意数据类型

变量在程序里用一个变量名来表示。变量名必须是大小写英文、数字和 _ 的组合,且不能用数字开头

python
a = 1           # a 是整数
t_007 = 'T007'  # t_007 是字符串
Answer = True   # Answer 是布尔值
print(a, t_007, Answer)

运行结果:

1 T007 True

⚠️ 命名规则总结

  • 可以用字母、数字、下划线 _
  • 不能以数字开头(1abc 是错的);
  • 不能用 Python 关键字(如 ifforclass 等);
  • 严格区分大小写(Answeranswer 是两个不同的变量)。

7.2 赋值语句 =

在 Python 中,等号 =赋值语句,可以把任意数据类型赋给变量。同一个变量可以反复赋值,而且可以是不同类型

python
a = 123        # a 是整数
print(a)
a = 'ABC'      # a 变成字符串
print(a)

运行结果:

123
ABC

7.3 动态语言 vs 静态语言

像 Python 这样"变量本身类型不固定"的语言,叫作动态语言。与之对应的是静态语言,静态语言在定义变量时必须指定类型,如果赋值时类型不匹配就会报错。

例如 Java 是静态语言(// 表示注释):

java
int a = 123;      // a 是整数类型变量
a = "ABC";        // 错误:不能把字符串赋给整型变量

而 Python 是动态语言,想赋什么类型都行。这就是动态语言更灵活的原因。

7.4 赋值语句的等号 ≠ 数学等号(重要!)

请不要把赋值语句的等号等同于数学的等号。 看下面的代码:

python
x = 10
x = x + 2
print(x)

运行结果:

12

如果从数学上理解 x = x + 2,无论如何都不成立。但在程序里,赋值语句是先计算右边x + 2,得到 12再赋给左边x。由于 x 之前是 10,重新赋值后就变成了 12

7.5 变量在内存中的表示(核心概念!)

理解变量在计算机内存中的表示非常重要。当我们写:

python
a = 'ABC'

Python 解释器干了两件事:

  1. 在内存中创建了一个 'ABC' 字符串;
  2. 在内存中创建了一个名为 a 的变量,并把它指向 'ABC'

可以把变量想象成一张"标签",它贴在内存里的数据上,而不是把数据装进变量里。

7.6 把一个变量赋给另一个变量

也可以把一个变量 a 赋值给另一个变量 b。这个操作实际上是让 b 指向 a 所指向的数据

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

运行结果:

ABC

最后 b 打印出来是 'ABC' 还是 'XYZ' 答案是 'ABC'。如果你从数学意义上理解,会错误地以为 ba 相同,应该是 'XYZ'。让我们一步步看发生了什么:

  1. 执行 a = 'ABC':解释器创建了字符串 'ABC' 和变量 aa 指向 'ABC'
  2. 执行 b = a:解释器创建了变量 bb 指向 a 所指向的 'ABC'
  3. 执行 a = 'XYZ':解释器创建了新的字符串 'XYZ',把 a 的指向改为 'XYZ',但 b 并没有跟着改。

所以最后 b 指向的还是原来的 'ABC'

⚠️ 易错点:这一步特别容易和"可变类型"的赋值搞混。本节 b = a 再改 a,是针对不可变的字符串,改 a 是让 a 换一个指向,不影响 b。但如果 a 是列表这种可变类型b = a 后修改内容,b 会跟着变。这两种情况要区分清楚(可变类型详见后续章节)。


八、常量

8.1 什么是常量

常量就是"不能变的变量",比如数学常数 π 就是一个常量。在 Python 中,通常用全部大写的变量名表示常量:

python
PI = 3.14159265359

8.2 常量其实只是个约定

但事实上,PI 仍然是一个变量——Python 没有任何机制保证 PI 不会被改变。用全部大写表示常量,只是习惯上的约定。如果你非要改 PI 的值,也没人能拦住你:

python
PI = 3.14159265359
PI = 3        # 技术上完全合法,只是破坏了约定
print(PI)

运行结果:

3

💡 记忆点:Python 没有真正意义上的常量,只有"约定俗成的大写常量"。看到全大写的变量名(如 PIMAX_SIZE),就当它是常量、不要改它,这是程序员的默契。


九、除法与取余

9.1 两种除法:///

Python 里有两种除法,这是初学者最容易搞混的地方。

/(普通除法):结果永远是浮点数,即使两个整数恰好整除:

python
print(10 / 3)     # 除不尽
print(9 / 3)      # 能整除,结果也是浮点数

运行结果:

3.3333333333333335
3.0

//(地板除):只取商的整数部分,结果永远是整数:

python
print(10 // 3)    # 3

运行结果:

3

9.2 取余运算 %

// 只取整数部分,那余数怎么办?Python 提供了 % 取余运算:

python
print(10 % 3)     # 10 除以 3 的余数

运行结果:

1

9.3 为什么整数运算永远是精确的

无论是 // 还是 %整数运算的结果永远是整数,所以整数运算永远是精确的。而 / 会得到浮点数,浮点数就可能出现前面提到的四舍五入误差。

运算符名称示例结果
/除法10 / 33.3333333333333335(float)
//地板除10 // 33(int)
%取余10 % 31(int)

💡 实用技巧

  • 判断奇偶:n % 2 == 0 是偶数,n % 2 == 1 是奇数;
  • 判断能否整除:n % m == 0

十、动手练习

请打印出以下变量的值,并写出输出结果:

python
n = 123
f = 456.789
s1 = 'Hello, world'
s2 = 'Hello, \'Adam\''
s3 = r'Hello, "Bart"'
s4 = r'''Hello,
Bob!'''

print(n)
print(f)
print(s1)
print(s2)
print(s3)
print(s4)

思考题:

  1. 10 / 410 // 4 的结果分别是多少?类型一样吗?

  2. 下面代码最后打印什么?为什么?

    python
    a = 'hello'
    b = a
    a = 'world'
    print(b)
  3. 0.1 + 0.2 == 0.3 的结果是 True 还是 False?为什么?


十一、小结

  1. 五种基础数据类型:整数 int、浮点数 float、字符串 str、布尔值 bool、空值 None
  2. 整数没有大小限制,可用十六进制(0x)、二进制(0b)、八进制(0o)表示,可用下划线分隔大数。
  3. 浮点数有精度误差0.1 + 0.2 != 0.3),涉及钱要用整数或 decimal
  4. 字符串'" 包裹,转义用 \,原始字符串用 r'',多行用 '''...'''
  5. 布尔值只有 True/Falseand 是"都真才真"、or 是"有真就真"、not 是取反。
  6. 变量是"指向数据的标签"a = 'ABC' 是让 a 指向 'ABC'b = a 是让 b 也指向同一个数据;之后改 a 不会影响 b
  7. Python 是动态语言,变量类型不固定;赋值语句的 = 不是数学等号,是"先算右边再赋给左边"。
  8. 常量是约定:全大写变量名表示常量,但 Python 并不会真正阻止你修改它。
  9. 两种除法/ 得到浮点数,// 得到整数(地板除),% 取余数;整数运算永远精确。
  10. 各类型常用方法
    • 整数:absdivmodpowbin/oct/hexbit_lengthto_bytes/from_bytes
    • 浮点数:roundis_integerhex/fromhexas_integer_ratiomath.floor/ceil/trunc
    • 字符串:split/joinstripreplacestartswith/endswithcount/indexencode/decodef-string
    • 布尔值:bool() 判断真假,True/False 继承自 int 的位操作和数值协议方法。

🎯 一句话总结:在 Python 内部,任何数据都可以看成一个"对象",而变量就是程序中用来指向这些对象的"标签";对变量赋值,本质就是把"标签"贴到某个对象上。每种数据类型都自带一批方法,掌握它们能让代码更简洁高效。