Part 1:Python语言核心 - 内建数据类型

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,而是:

  1. 创建新对象 2
  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 的情况:

  • 0
  • 0.0
  • 0j
  • None
  • ""
  • []
  • {}

📌 这是控制流执行模型的一部分

NoneType 唯一的空对象

None 是什么?

复制代码
None is None  # 永远 True
  • None 是一个 单例对象
  • 类型是 NoneType

None 的设计意义

  • 表示"没有值"

  • 表示"尚未返回"

  • 表示"空占位"

    def f():
    pass

    print(f()) # None

📌 None ≠ 0 ≠ False ≠ ""

为什么要用 is None

复制代码
x == None   # 不推荐
x is None   # 推荐

原因:

  • None 是单例
  • is 比较身份
  • 避免被重载 __eq__

基本类型的共同特征总结

特性 说明
不可变 修改 = 新对象
内建 C 层实现
高度优化 小整数缓存
可哈希 可作 dict key
生命周期长 常驻内存
相关推荐
IT 行者7 小时前
Web逆向工程AI工具:JSHook MCP,80+专业工具让Claude变JS逆向大师
开发语言·javascript·ecmascript·逆向
程序员 沐阳8 小时前
JavaScript 内存与引用:深究深浅拷贝、垃圾回收与 WeakMap/WeakSet
开发语言·javascript·ecmascript
Mr_Xuhhh9 小时前
Java泛型进阶:从基础到高级特性完全指南
开发语言·windows·python
He1955019 小时前
wordpress搭建块
开发语言·wordpress·古腾堡·wordpress块
老天文学家了9 小时前
蓝桥杯备战Python
开发语言·python
赫瑞9 小时前
数据结构中的排列组合 —— Java实现
java·开发语言·数据结构
初夏睡觉10 小时前
c++1.3(变量与常量,简单数学运算详解),草稿公放
开发语言·c++
升职佳兴10 小时前
C盘爆满自救:3步无损迁移应用数据到E盘(含回滚)
c语言·开发语言
ID_1800790547310 小时前
除了 Python,还有哪些语言可以解析 JSON 数据?
开发语言·python·json
周末也要写八哥11 小时前
多进程和多线程的特点和区别
java·开发语言·jvm