从数字到字节:一次讲清 Python 基础数据类型

2026-10-03 21 预计阅读时间: 1 分钟
来源: realpython.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Python 内置的数字、字符串、字节序列和布尔值看似简单,却决定了数据如何计算、比较、编码与传输。理解这些类型的行为,能减少浮点误差、文本编码异常和隐式类型转换带来的问题。

数字不只有整数和小数

Python 常用的数字类型包括 int、float 和 complex。

  • int 表示整数,大小通常不受固定 32 位或 64 位范围限制,而是受可用内存约束。
  • float 表示浮点数,适合一般科学计算,但不能精确表示所有十进制小数。
  • complex 表示复数,使用 j 标记虚部,例如 3 + 4j。
integer_value = 42
float_value = 0.1 + 0.2
complex_value = 3 + 4j

print(type(integer_value), integer_value)
print(type(float_value), float_value)
print(type(complex_value), complex_value)
print(complex_value.real, complex_value.imag)

运行后通常会看到 0.1 + 0.2 并不严格等于 0.3:

print(0.1 + 0.2 == 0.3)  # False

这是二进制浮点表示的结果,而不是 Python 的计算错误。比较浮点数时,可以使用 math.isclose():

import math

result = 0.1 + 0.2
print(math.isclose(result, 0.3, rel_tol=1e-9, abs_tol=0.0))  # True

如果业务涉及金额,可以这样实践:使用 decimal.Decimal,并通过字符串构造十进制数,避免先引入浮点误差。

from decimal import Decimal

price = Decimal("19.90")
quantity = 3
total = price * quantity

print(total)  # 59.70

字符串表示文本,字节表示编码后的数据

str 用于保存 Unicode 文本,bytes 用于保存原始字节。两者表面上都像序列,但不能直接拼接或比较为相同内容。

text = "Python 数据类型"
payload = text.encode("utf-8")
restored = payload.decode("utf-8")

print(text)
print(payload)
print(restored)
print(text == restored)  # True

这里有一条实用边界:

  • 用户输入、JSON 字段和程序内部文本通常使用 str。
  • 文件内容、网络响应体、图片和加密数据在底层通常表现为 bytes。
  • 从文本变成字节时调用 encode();从字节恢复文本时调用 decode()。

编码和解码必须采用兼容的字符编码,否则会出现乱码或 UnicodeDecodeError。例如,下面的字节来自 UTF-8,就不应该按 ASCII 解码:

message = "你好".encode("utf-8")

try:
    print(message.decode("ascii"))
except UnicodeDecodeError as exc:
    print(f"解码失败: {exc}")

str 和 bytes 都是不可变对象。所谓“修改字符串”,实际上会创建一个新对象:

name = "python"
updated_name = name.capitalize()

print(name)          # python
print(updated_name)  # Python

处理大量二进制数据且需要原地修改时,可以考虑可变的 bytearray:

packet = bytearray(b"ABC")
packet[0] = ord("Z")
print(packet)  # bytearray(b'ZBC')

布尔值也是一种特殊的数字

Python 的布尔类型只有两个值:True 和 False。它常用于条件判断,同时也是 int 的子类:

print(isinstance(True, bool))  # True
print(isinstance(True, int))   # True
print(True + True + False)     # 2

这种设计让布尔值可以参与统计。例如,可以直接计算一组条件中有多少项成立:

checks = [
    len("python") > 3,
    10 % 2 == 0,
    "x" in "data",
]

passed = sum(checks)
print(f"通过 {passed}/{len(checks)} 项检查")

不过,能把布尔值当整数使用,不代表总应该这样做。业务代码如果需要表达计数,显式转换成 int 或使用清晰的变量名,通常更容易维护。

条件语句还会对其他类型执行真假判断。常见的假值包括:

  • False
  • 数字零,如 0、0.0 和 0j
  • 空字符串 ""
  • 空字节串 b""
  • 空容器,如 []、{} 和 set()
  • None
values = [0, 1, "", "Python", b"", b"data", None]

for value in values:
    print(repr(value), "=>", bool(value))

需要注意,字符串 "False" 并不是假值,因为它是一个非空字符串:

print(bool("False"))  # True
print(bool("0"))      # True

读取环境变量或配置文件时,不要直接用 bool(text) 解析开关。可以这样实践:

def parse_bool(value: str) -> bool:
    normalized = value.strip().lower()
    if normalized in {"true", "1", "yes", "on"}:
        return True
    if normalized in {"false", "0", "no", "off"}:
        return False
    raise ValueError(f"无法识别的布尔值: {value!r}")

print(parse_bool("YES"))   # True
print(parse_bool(" off ")) # False

一段可直接运行的类型检查程序

将下面代码保存为 basic_types.py,然后执行 python basic_types.py。它集中演示类型识别、文本编码和真假判断。

from typing import Any


def describe(value: Any) -> None:
    print(
        f"value={value!r:<20} "
        f"type={type(value).__name__:<8} "
        f"truthy={bool(value)}"
    )


values = [
    42,
    3.14,
    2 + 5j,
    "Python",
    "",
    b"Python",
    True,
    False,
]

for item in values:
    describe(item)

text = "类型"
data = text.encode("utf-8")

print("编码结果:", data)
print("解码结果:", data.decode("utf-8"))

运行命令:

python basic_types.py

使用这些类型时的检查清单

在实际项目中,可以用以下问题快速确认类型选择是否合理:

  1. 这是需要计算的数字,还是只具有数字外观的标识符?手机号、邮编和订单号通常应保存为字符串。
  2. 是否要求精确的十进制计算?如果是金额等场景,应评估 Decimal,不要默认使用 float。
  3. 当前变量代表人类可读文本还是原始字节?跨越文件和网络边界时,要明确编码格式。
  4. 布尔值是否来自字符串配置?如果是,应显式解析,而不是依赖非空字符串的真值。
  5. 是否在混合不同类型?Python 不会自动把 "3" 当作数字 3,转换应当明确并处理失败情况。

基础类型本身并不复杂,真正容易出错的是类型边界。把数字精度、字符编码和真假规则写清楚,程序的数据流就会稳定得多。


相关推荐