Python 数据类型 - 内建数据类型
基本类型 = Python 运行时最底层、最稳定、最常被优化的一类对象。
它们的共同点:
- 都是 内建类型(built-in types)
- 都是 不可变对象(immutable)
- 都有 明确的 C 层实现
- 都深度参与 Python 的执行优化
先统一一个底层视角
在 Python 里:
x = 10
不是"x 里存了 10",而是:
x ─────▶ PyObject(int, value=10)
所有基本类型对象都满足:
- 有
id()(内存身份) - 有
type() - 有引用计数
- 由 Python 垃圾回收系统管理
📌 这点非常重要 :
int / float / bool / None,只是对象的不同形态。
int 任意精度整数
Python 的 int 是"任意精度整数"。
a = 10
b = 10**100
- 不会溢出
- 位数只受内存限制
📌 对比 C / Java:
- C / Java:32 / 64 位
- Python:动态扩展
int 的底层特点
- 存储的是 二进制大整数
- 每次"修改"都会创建新对象(不可变)
- 小整数会被缓存(优化)
python
a = 256
b = 256
a is b # True(常见实现)
a = 257
b = 257
a is b # 可能 False
📌 原因:
Python 为了性能,对常用小整数做了对象复用
int 运算的执行模型
a = 1
a += 1
不是修改 1,而是:
- 创建新对象
2 a重新绑定到2
float 双精度浮点数
Python 的 float = C 的 double
-
64 位
-
IEEE 754 标准
-
有精度误差
0.1 + 0.2 == 0.3 # False
📌 这不是 Python 的 bug,而是 浮点数的本质
为什么会有精度误差
因为:
0.1 → 二进制是无限循环小数
Python只能截断存储。
python
import decimal
decimal.Decimal("0.1") + decimal.Decimal("0.2")
📌 认知重点:
- float 是"近似值"
- 金融、精确计算不要用 float
十进制转二进制的原理
在二进制中,小数部分使用 2⁻¹、2⁻²、2⁻³... 表示:
0.5十进制 =0.1二进制(因为1 × 2⁻¹ = 0.5)0.25十进制 =0.01二进制(因为0 × 2⁻¹ + 1 × 2⁻² = 0.25)
0.1 十进制转二进制:
tex
0.1 × 2 = 0.2 → 0
0.2 × 2 = 0.4 → 0
0.4 × 2 = 0.8 → 0
0.8 × 2 = 1.6 → 1
0.6 × 2 = 1.2 → 1
0.2 × 2 = 0.4 → 0 (开始循环)
- 所以
0.1十进制 =0.000110011001100110011...(无限循环二进制)
0.2 十进制转二进制 :
由于 0.2 = 2 × 0.1,所以二进制表示是 0.0011001100110011...(同样无限循环)
IEEE 754 双精度浮点数的存储限制
Python 使用 IEEE 754 双精度浮点数(64位):
- 1 位符号位
- 11 位指数位
- 52 位尾数位(有效数字)
这意味着只能存储 52 位二进制有效数字 ,超出的部分会进行舍入(rounding)。
python
# 真实存储值
print(f"{0.1:.55f}") # 0.1000000000000000055511151231257827021181583404541015625
print(f"{0.2:.55f}") # 0.2000000000000000111022302462515654042363166809082031250
print(f"{0.3:.55f}") # 0.2999999999999999888977697537484345957636833190917968750
误差累加后会越来越大。金融计算切忌使用 float,首选 Python 的 Decimal 标准库模块。
complex 复数
z = 1 + 2j
-
实部:
z.real -
虚部:
z.imag -
不支持大小比较
(1+2j) > (2+3j) # TypeError
📌 原因:
数学上复数没有"大小"定义
bool 继承自 int
bool 的真实身份
python
issubclass(bool, int) # True
True == 1 # True
False == 0 # True
📌 但:
python
True is 1 # False
为什么 bool 继承 int?
历史 + 实用主义:
- 逻辑运算可以直接参与数值计算
sum([True, False, True]) == 2
真值判断(非常重要)
bool(x)
为 False 的情况:
00.00jNone""[]{}
📌 这是控制流执行模型的一部分
NoneType 唯一的空对象
None 是什么?
None is None # 永远 True
None是一个 单例对象- 类型是
NoneType
None 的设计意义
-
表示"没有值"
-
表示"尚未返回"
-
表示"空占位"
def f():
passprint(f()) # None
📌 None ≠ 0 ≠ False ≠ ""
为什么要用 is None?
x == None # 不推荐
x is None # 推荐
原因:
None是单例is比较身份- 避免被重载
__eq__
基本类型的共同特征总结
| 特性 | 说明 |
|---|---|
| 不可变 | 修改 = 新对象 |
| 内建 | C 层实现 |
| 高度优化 | 小整数缓存 |
| 可哈希 | 可作 dict key |
| 生命周期长 | 常驻内存 |