Python3 数据类型与变量
目录
- 一、为什么要有数据类型
- 二、整数 int
- 三、浮点数 float
- 四、字符串 str
- 五、布尔值 bool
- 六、空值 None
- 七、变量(核心重点)
- 八、常量
- 九、除法与取余
- 十、动手练习
- 十一、小结
一、为什么要有数据类型
计算机,顾名思义,最早就是用来做数学计算的机器,所以它理所当然能处理各种数值。但计算机能处理的远不止数值——还能处理文本、图形、音频、视频、网页等五花八门的数据。
不同的数据,需要定义不同的数据类型(Data Type)。就像超市里饮料放冷柜、大米放粮区、电池放收银台旁,分门别类才好管理;程序里的数据也要分类,因为不同类型的数据,存放方式和使用方法都不一样。
Python 中能够直接处理的基础数据类型,主要有下面几种:
| 类型 | 关键字 | 例子 | 一句话说明 |
|---|---|---|---|
| 整数 | int | 1、-8、0 | 没有小数点的数 |
| 浮点数 | float | 3.14、1.5e3 | 小数,也叫浮点数 |
| 字符串 | str | 'abc'、"xyz" | 一串文字 |
| 布尔值 | bool | True、False | 只有"真/假"两种值 |
| 空值 | NoneType | None | 表示"什么都没有" |
除此之外,Python 还提供了列表、字典等多种数据类型,以及允许自定义类型,这些会在后续章节展开。
💡 小提示:学习任何编程语言,数据类型都是第一块基石。记住这张表,后面的变量、运算、判断全都建立在它之上。
二、整数 int
2.1 任意大小的整数
Python 可以处理任意大小的整数,正数、负数、零都可以,写法和数学里一模一样:
a = 1
b = -8080
c = 0
print(a, b, c)运行结果:
1 -8080 0💡 Python 的独特优势:很多语言(比如 Java)的整数是有大小上限的,32 位整数最大只能到
2147483647。而 Python 的整数没有大小限制,只要内存够大,几百位的数字也能直接算。
2.2 用十六进制表示整数
计算机内部使用二进制。有时候用十六进制表示整数会更方便,用 0x 作前缀、0-9 和 a-f 表示:
print(0xff00) # 十六进制,等于十进制的 65280
print(0xa5b4c3d2) # 一个很大的十六进制数运行结果:
65280
2778211282除了十六进制,Python 还支持二进制(0b 开头)和八进制(0o 开头):
print(0b1010) # 二进制 1010,等于十进制 10
print(0o17) # 八进制 17,等于十进制 15
print(0x1F) # 十六进制 1F,等于十进制 31运行结果:
10
15
312.3 用下划线分隔大数
对于很大的数,比如 10000000000,很难一眼数清楚有几个 0。Python 允许在数字中间用 _ 分隔,方便阅读:
print(10_000_000_000) # 和 10000000000 完全一样
print(0xa1b2_c3d4) # 十六进制也可以加下划线运行结果:
10000000000
2713871348💡
_只是给人看的"千位分隔符",Python 在计算时会自动忽略它,不影响数值本身。
2.4 整数运算永远是精确的
两个整数做加减乘除,结果永远是精确的,不会出现四舍五入的误差:
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
把十进制整数转成二进制、八进制、十六进制的字符串:
print(bin(10)) # 二进制,'0b1010'
print(oct(15)) # 八进制,'0o17'
print(hex(31)) # 十六进制,'0x1f'运行结果:
0b1010
0o17
0x1f💡 注意:
bin()/oct()/hex()返回的是字符串,且自带前缀(0b/0o/0x)。反过来把字符串转回整数,用int(s, 进制):
print(int('1010', 2)) # 二进制字符串转十进制:10
print(int('17', 8)) # 八进制:15
print(int('1f', 16)) # 十六进制:31运行结果:
10
15
31(2)绝对值:abs
print(abs(-7))
print(abs(7))运行结果:
7
7(3)divmod:一次得到商和余数
divmod(a, b) 返回一个元组 (商, 余数),等价于 (a // b, a % b):
print(divmod(10, 3)) # (3, 1)运行结果:
(3, 1)(4)pow:幂运算
print(pow(2, 10)) # 2 的 10 次方 = 1024
print(pow(2, 10, 1000)) # 2**10 % 1000 = 24(第三个参数是取模)运行结果:
1024
24(5)bit_length / bit_count:位操作
n = 10
print(n.bit_length()) # 二进制表示需要几位:10 = 0b1010,需要 4 位
print((0b1010).bit_count()) # 二进制里 1 的个数(Python 3.10+)运行结果:
4
2(6)max / min / sum:批量统计
print(max(1, 5, 3)) # 最大值
print(min(1, 5, 3)) # 最小值
print(sum([1, 2, 3, 4])) # 求和运行结果:
5
1
10(7)to_bytes / from_bytes:整数与字节互转
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+)
print((10).as_integer_ratio()) # (10, 1)运行结果:
(10, 1)(9)is_integer / real / imag / numerator / denominator:数值协议属性
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:共轭复数
print((3 + 4j).conjugate()) # (3-4j)
print((42).conjugate()) # 42(整数的共轭是自己)运行结果:
(3-4j)
42(11)index:支持切片和索引
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💡 小结:整数自身的方法不多,更多是靠内置函数(
abs、divmod、pow、bin、oct、hex、max、min、sum)来操作。to_bytes/from_bytes在网络编程和二进制文件处理中常用;real/imag/conjugate是为了兼容复数协议而存在的。
三、浮点数 float
3.1 什么是浮点数
浮点数就是小数。之所以叫"浮点",是因为按科学记数法表示时,小数点位置是"浮动"的。例如 1.23 × 10⁹ 和 12.3 × 10⁸ 是完全相等的——小数点位置变了,但值没变。
普通写法:
pi = 3.14
price = 9.9
print(pi, price)运行结果:
3.14 9.93.2 科学计数法
对于很大或很小的浮点数,必须用科学计数法表示,把 10 换成字母 e:
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-053.3 浮点数可能有误差(重要!)
整数运算永远是精确的,但浮点数运算可能会有四舍五入的误差。这是所有计算机的通病,不是 Python 的 bug:
print(0.1 + 0.2)运行结果:
0.30000000000000004你期望是 0.3,结果却是 0.30000000000000004。原因是浮点数在计算机内部用二进制存储,而 0.1、0.2 这样的十进制小数无法用二进制精确表示。
⚠️ 怎么应对:涉及钱的精确计算,不要直接用浮点数比大小或相加。可以用整数"以分为单位"存储,或者用
round()取近似值,进阶时再用decimal模块。pythonprint(round(0.1 + 0.2, 10) == 0.3) # True
💡 另一个细节:Python 的浮点数虽然也有范围,但超出一定范围会直接表示为
inf(无穷大),而不是报错:pythonprint(1e400) # 超出范围,显示为 inf
3.4 浮点数的常用方法与内置函数
浮点数除了加减乘除,还有一些专门的方法和配套函数。
(1)round:四舍五入
print(round(3.14159, 2)) # 保留 2 位小数:3.14
print(round(3.14159)) # 不传位数,取整:3运行结果:
3.14
3(2)is_integer:判断小数部分是否为 0
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:十六进制表示
print((1.5).hex()) # '0x1.8000000000000p+0'
print(float.fromhex('0x1.8000000000000p+0')) # 1.5运行结果:
0x1.8000000000000p+0
1.5(4)as_integer_ratio:转成分数
print(0.75.as_integer_ratio()) # (3, 4),即 3/4运行结果:
(3, 4)(5)math 模块的配套函数
浮点运算经常配合 math 标准库使用:
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:复数协议兼容
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:格式化输出
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:数值状态判断
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_integer、hex、as_integer_ratio是浮点数自身的方法;isfinite/isinf/isnan需要math模块。
四、字符串 str
4.1 用引号包起来的文本
字符串是用单引号 ' 或双引号 " 包起来的任意文本:
s1 = 'abc'
s2 = "xyz"
print(s1, s2)运行结果:
abc xyz💡 重要理解:
''或""本身只是"标记",不是字符串内容的一部分。所以'abc'这个字符串只有a、b、c这 3 个字符,不含引号。
4.2 字符串里要包含引号怎么办
如果字符串内部本身有 ',就可以用双引号把它包起来:
s = "I'm OK"
print(s)运行结果:
I'm OK那如果字符串里 ' 和 " 都有呢?可以用转义字符 \ 来标识:
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() 打印一下,能更直观地看到转义效果:
print('I\'m ok.')
print('I\'m learning\nPython.')
print('\\\n\\')运行结果:
I'm ok.
I'm learning
Python.
\
\4.4 原始字符串 r''(不转义)
如果字符串里有很多字符都需要转义,就要写一大堆 \,很麻烦。Python 允许用 r'' 表示"原始字符串"——内部字符默认不转义:
print('\\\t\\') # 普通字符串:\t 被转义成制表符
print(r'\\\t\\') # 原始字符串:原样输出,不转义运行结果:
\ \
\\\t\\💡 什么时候用
r'':最典型的就是 Windows 文件路径,比如r'C:\Users\name'。如果不用r,就得写成'C:\\Users\\name',非常啰嗦。
4.5 多行字符串 '''...'''
如果字符串里有很多换行,用 \n 写在一行里很难阅读。Python 允许用 '''...''' 表示多行内容:
print('''line1
line2
line3''')运行结果:
line1
line2
line3💡 交互式命令行的细节:在
>>>提示符下输入多行内容时,提示符会从>>>变成...,表示"接着上一行继续输入"。注意...是提示符,不是代码的一部分。写完结束符'''后回车,才会执行这条语句。
多行字符串 '''...''' 前面也能加 r,让多行内容也不转义:
print(r'''hello,\n
world''')运行结果:
hello,\n
world💡 三引号的另一用途:
'''...'''还常用来写多行注释和文档字符串(docstring),本质就是一个"没被使用的字符串"。
4.6 字符串的更多常用方法
字符串是方法最丰富的数据类型。前面讲了拼接、切片、转义,这里再补充一批高频方法(strip、split、replace、find 等已在《Python3 基本数据类型》中详细介绍,此处不重复)。
(1)大小写转换的补充
s = "Hello World"
print(s.swapcase()) # 大小写互换:hELLO wORLD
print(s.capitalize()) # 首字母大写,其余小写:Hello world
print(s.casefold()) # 更彻底的小写(适合忽略大小写比较)运行结果:
hELLO wORLD
Hello world
hello world(2)对齐与填充
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)更多判断方法
print("HELLO".isupper()) # 是否全大写
print("hello".islower()) # 是否全小写
print("Hello".istitle()) # 是否每个单词首字母大写
print("123".isdecimal()) # 是否全是十进制数字(含全角)
print("1_000".isidentifier()) # 是否是合法变量名运行结果:
True
True
True
True
True(4)反向查找:rfind / rindex
s = "hello world hello"
print(s.find("hello")) # 从左找,第一次出现的位置:0
print(s.rfind("hello")) # 从右找,最后一次出现的位置:12运行结果:
0
12(5)partition:按分隔符一分为三
s = "2026-08-27"
print(s.partition("-")) # ('2026', '-', '08-27')运行结果:
('2026', '-', '08-27')(6)splitlines:按换行拆分
text = "第一行\n第二行\n第三行"
print(text.splitlines()) # ['第一行', '第二行', '第三行']运行结果:
['第一行', '第二行', '第三行'](7)removeprefix / removesuffix(Python 3.9+)
s = "prefix_hello"
print(s.removeprefix("prefix_")) # hello
print("hello.txt".removesuffix(".txt")) # hello运行结果:
hello
hello(8)split / rsplit / join:拆分与拼接
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:去除首尾字符
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:替换
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:开头结尾判断
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:统计与定位
s = "hello world hello"
print(s.count("hello")) # 出现次数:2
print(s.index("world")) # 第一次出现位置:6
# print(s.index("xyz")) # 找不到会报 ValueError运行结果:
2
6(13)encode / decode:编码转换
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:格式化输出
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:字符映射替换
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
布尔值和布尔代数完全一致,一个布尔值只有 True、False 两种值,要么是 True,要么是 False。可以直接写,也可以通过比较运算得到:
print(True)
print(False)
print(3 > 2) # 比较结果是布尔值
print(3 > 5)运行结果:
True
False
True
False⚠️ 注意大小写:
True和False首字母必须大写!写true/false会报NameError。
5.2 布尔运算:and、or、not
布尔值可以用 and、or、not 做运算。
and(与运算):只有两边都为 True,结果才是 True:
print(True and True) # True
print(True and False) # False
print(False and False) # False
print(5 > 3 and 3 > 1) # Trueor(或运算):只要有一边为 True,结果就是 True:
print(True or True) # True
print(True or False) # True
print(False or False) # False
print(5 > 3 or 1 > 3) # Truenot(非运算):单目运算符,取反:
print(not True) # False
print(not False) # True
print(not 1 > 2) # True(1 > 2 是 False,取反后是 True)5.3 布尔值常用在条件判断里
布尔值最常出现在 if 判断中:
age = 20
if age >= 18:
print('adult')
else:
print('teenager')运行结果:
adult💡 记忆口诀:
and是"都真才真",or是"有真就真",not是"真假颠倒"。
5.4 布尔值的转换与细节
布尔值自身没多少方法,但有几个实用细节值得记住。
(1)bool():任何值都能判断真假
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——0、0.0、""(空字符串)、[](空列表)、()(空元组)、{}(空字典)、set()(空集合)、None。其余一律当作True。
(2)True / False 本质是 1 和 0
布尔值是 int 的子类,True 相当于 1,False 相当于 0:
print(int(True)) # 1
print(int(False)) # 0
print(True + True) # 2(因为 True 就是 1)运行结果:
1
0
2⚠️ 提醒:虽然
True == 1成立,但True和1的类型不同。判断相等用==,判断"是不是同一个对象"用is,别混用。
(3)bit_length / bit_count:继承自 int 的位操作
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:复数协议兼容
print(True.conjugate()) # 1
print(True.real) # 1
print(True.imag) # 0运行结果:
1
1
0(5)and / or / xor:位运算的魔术方法
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,因为bool是int的子类。日常开发中几乎不会直接调用这些方法,但理解它们有助于明白"布尔值本质上是 0 和 1"这一设计。
六、空值 None
空值是 Python 里一个特殊的值,用 None 表示。
x = None
print(x)
print(type(x))运行结果:
None
<class 'NoneType'>⚠️ 关键区分:
None不能理解为0!0是一个有意义的数字,而None是一个特殊的"空值",表示"这里什么都没有"。它和空字符串''、空列表[]也不是一回事——那些是"有类型但没内容",None是"根本没有值"。
💡 判断是否为 None:推荐用
is None,而不是== None:pythondata = None if data is None: print("还没有数据")
七、变量(核心重点)
7.1 变量是什么
变量的概念,基本和初中代数里的"方程变量"是一致的。只是程序里的变量更厉害——它不仅可以是数字,还可以是任意数据类型。
变量在程序里用一个变量名来表示。变量名必须是大小写英文、数字和 _ 的组合,且不能用数字开头:
a = 1 # a 是整数
t_007 = 'T007' # t_007 是字符串
Answer = True # Answer 是布尔值
print(a, t_007, Answer)运行结果:
1 T007 True⚠️ 命名规则总结:
- 可以用字母、数字、下划线
_;- 不能以数字开头(
1abc是错的);- 不能用 Python 关键字(如
if、for、class等);- 严格区分大小写(
Answer和answer是两个不同的变量)。
7.2 赋值语句 =
在 Python 中,等号 = 是赋值语句,可以把任意数据类型赋给变量。同一个变量可以反复赋值,而且可以是不同类型:
a = 123 # a 是整数
print(a)
a = 'ABC' # a 变成字符串
print(a)运行结果:
123
ABC7.3 动态语言 vs 静态语言
像 Python 这样"变量本身类型不固定"的语言,叫作动态语言。与之对应的是静态语言,静态语言在定义变量时必须指定类型,如果赋值时类型不匹配就会报错。
例如 Java 是静态语言(// 表示注释):
int a = 123; // a 是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量而 Python 是动态语言,想赋什么类型都行。这就是动态语言更灵活的原因。
7.4 赋值语句的等号 ≠ 数学等号(重要!)
请不要把赋值语句的等号等同于数学的等号。 看下面的代码:
x = 10
x = x + 2
print(x)运行结果:
12如果从数学上理解 x = x + 2,无论如何都不成立。但在程序里,赋值语句是先计算右边的 x + 2,得到 12,再赋给左边的 x。由于 x 之前是 10,重新赋值后就变成了 12。
7.5 变量在内存中的表示(核心概念!)
理解变量在计算机内存中的表示非常重要。当我们写:
a = 'ABC'Python 解释器干了两件事:
- 在内存中创建了一个
'ABC'字符串; - 在内存中创建了一个名为
a的变量,并把它指向'ABC'。
可以把变量想象成一张"标签",它贴在内存里的数据上,而不是把数据装进变量里。
7.6 把一个变量赋给另一个变量
也可以把一个变量 a 赋值给另一个变量 b。这个操作实际上是让 b 指向 a 所指向的数据:
a = 'ABC'
b = a
a = 'XYZ'
print(b)运行结果:
ABC最后 b 打印出来是 'ABC' 还是 'XYZ'? 答案是 'ABC'。如果你从数学意义上理解,会错误地以为 b 和 a 相同,应该是 'XYZ'。让我们一步步看发生了什么:
- 执行
a = 'ABC':解释器创建了字符串'ABC'和变量a,a指向'ABC'; - 执行
b = a:解释器创建了变量b,b指向a所指向的'ABC'; - 执行
a = 'XYZ':解释器创建了新的字符串'XYZ',把a的指向改为'XYZ',但b并没有跟着改。
所以最后 b 指向的还是原来的 'ABC'。
⚠️ 易错点:这一步特别容易和"可变类型"的赋值搞混。本节
b = a再改a,是针对不可变的字符串,改a是让a换一个指向,不影响b。但如果a是列表这种可变类型,b = a后修改内容,b会跟着变。这两种情况要区分清楚(可变类型详见后续章节)。
八、常量
8.1 什么是常量
常量就是"不能变的变量",比如数学常数 π 就是一个常量。在 Python 中,通常用全部大写的变量名表示常量:
PI = 3.141592653598.2 常量其实只是个约定
但事实上,PI 仍然是一个变量——Python 没有任何机制保证 PI 不会被改变。用全部大写表示常量,只是习惯上的约定。如果你非要改 PI 的值,也没人能拦住你:
PI = 3.14159265359
PI = 3 # 技术上完全合法,只是破坏了约定
print(PI)运行结果:
3💡 记忆点:Python 没有真正意义上的常量,只有"约定俗成的大写常量"。看到全大写的变量名(如
PI、MAX_SIZE),就当它是常量、不要改它,这是程序员的默契。
九、除法与取余
9.1 两种除法:/ 和 //
Python 里有两种除法,这是初学者最容易搞混的地方。
/(普通除法):结果永远是浮点数,即使两个整数恰好整除:
print(10 / 3) # 除不尽
print(9 / 3) # 能整除,结果也是浮点数运行结果:
3.3333333333333335
3.0//(地板除):只取商的整数部分,结果永远是整数:
print(10 // 3) # 3运行结果:
39.2 取余运算 %
// 只取整数部分,那余数怎么办?Python 提供了 % 取余运算:
print(10 % 3) # 10 除以 3 的余数运行结果:
19.3 为什么整数运算永远是精确的
无论是 // 还是 %,整数运算的结果永远是整数,所以整数运算永远是精确的。而 / 会得到浮点数,浮点数就可能出现前面提到的四舍五入误差。
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
/ | 除法 | 10 / 3 | 3.3333333333333335(float) |
// | 地板除 | 10 // 3 | 3(int) |
% | 取余 | 10 % 3 | 1(int) |
💡 实用技巧:
- 判断奇偶:
n % 2 == 0是偶数,n % 2 == 1是奇数;- 判断能否整除:
n % m == 0。
十、动手练习
请打印出以下变量的值,并写出输出结果:
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)思考题:
10 / 4和10 // 4的结果分别是多少?类型一样吗?下面代码最后打印什么?为什么?
pythona = 'hello' b = a a = 'world' print(b)0.1 + 0.2 == 0.3的结果是True还是False?为什么?
十一、小结
- 五种基础数据类型:整数
int、浮点数float、字符串str、布尔值bool、空值None。 - 整数没有大小限制,可用十六进制(
0x)、二进制(0b)、八进制(0o)表示,可用下划线分隔大数。 - 浮点数有精度误差(
0.1 + 0.2 != 0.3),涉及钱要用整数或decimal。 - 字符串用
'或"包裹,转义用\,原始字符串用r'',多行用'''...'''。 - 布尔值只有
True/False,and是"都真才真"、or是"有真就真"、not是取反。 - 变量是"指向数据的标签":
a = 'ABC'是让a指向'ABC';b = a是让b也指向同一个数据;之后改a不会影响b。 - Python 是动态语言,变量类型不固定;赋值语句的
=不是数学等号,是"先算右边再赋给左边"。 - 常量是约定:全大写变量名表示常量,但 Python 并不会真正阻止你修改它。
- 两种除法:
/得到浮点数,//得到整数(地板除),%取余数;整数运算永远精确。 - 各类型常用方法:
- 整数:
abs、divmod、pow、bin/oct/hex、bit_length、to_bytes/from_bytes; - 浮点数:
round、is_integer、hex/fromhex、as_integer_ratio、math.floor/ceil/trunc; - 字符串:
split/join、strip、replace、startswith/endswith、count/index、encode/decode、f-string; - 布尔值:
bool()判断真假,True/False继承自int的位操作和数值协议方法。
- 整数:
🎯 一句话总结:在 Python 内部,任何数据都可以看成一个"对象",而变量就是程序中用来指向这些对象的"标签";对变量赋值,本质就是把"标签"贴到某个对象上。每种数据类型都自带一批方法,掌握它们能让代码更简洁高效。