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
生命周期长 常驻内存
相关推荐
切糕师学AI2 小时前
编程语言 Erlang 简介
开发语言·erlang
sycmancia2 小时前
C++——C++中的类型识别
开发语言·c++
带娃的IT创业者2 小时前
WeClaw WebSocket 连接中断诊断:从频繁掉线到稳定长连的优化之路
python·websocket·网络协议·php·fastapi·实时通信
还是大剑师兰特2 小时前
Vue3 按钮切换示例(启动 / 关闭互斥显示)
开发语言·javascript·vue.js
GinoWi2 小时前
Chapter 5 Python中的元组
python
星空露珠2 小时前
迷你世界UGC3.0脚本Wiki角色模块管理接口 Actor
开发语言·数据库·算法·游戏·lua
我星期八休息2 小时前
深入理解哈希表
开发语言·数据结构·c++·算法·哈希算法·散列表
寻寻觅觅☆2 小时前
东华OJ-进阶题-19-排队打水问题(C++)
开发语言·c++·算法
前进的李工2 小时前
LangChain使用之Model IO(提示词模版之PromptTemplate)
开发语言·人工智能·python·langchain