Python 编程教程 / 04 - 变量与数据类型
第 04 章:变量与数据类型
理解 Python 的变量机制和内置数据类型,掌握类型转换与动态类型系统。
4.1 变量
4.1.1 变量的赋值
Python 的变量是对象的引用,而非存储值的容器。
x = 10 # x 引用整数对象 10
name = "Alice" # name 引用字符串对象 "Alice"
graph LR
x --> |引用| 10["int: 10"]
name --> |引用| Alice["str: 'Alice'"]
4.1.2 多重赋值
# 同时赋值多个变量
a, b, c = 1, 2, 3
# 交换变量(Pythonic 方式)
a, b = b, a
# 同一值赋给多个变量
x = y = z = 0
# 解包赋值
first, *rest = [1, 2, 3, 4, 5]
# first=1, rest=[2, 3, 4, 5]
first, *middle, last = [1, 2, 3, 4, 5]
# first=1, middle=[2, 3, 4], last=5
4.1.3 变量命名规则
| 规则 | 示例 |
|---|---|
| 字母或下划线开头 | _count, name |
| 只含字母、数字、下划线 | user_name, count2 |
| 区分大小写 | name ≠ Name |
| 避免使用保留字 | 不能用 class, def, import 等 |
# 查看 Python 保留字
import keyword
print(keyword.kwlist)
# ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', ...]
4.2 数字类型
4.2.1 整数(int)
# Python 3 的 int 没有大小限制
x = 42
big = 10 ** 100 # Googol
# 不同进制
binary = 0b1010 # 二进制 → 10
octal = 0o17 # 八进制 → 15
hexadecimal = 0xFF # 十六进制 → 255
# 下划线分隔(提高可读性)
population = 1_400_000_000
budget = 100_000.50
4.2.2 浮点数(float)
pi = 3.14159
e = 2.71828
speed_of_light = 3e8 # 科学计数法
# ⚠️ 浮点数精度问题
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
# 解决方案:使用 math.isclose() 或 decimal
import math
print(math.isclose(0.1 + 0.2, 0.3)) # True
from decimal import Decimal
result = Decimal("0.1") + Decimal("0.2")
print(result) # 0.3
4.2.3 复数(complex)
z = 3 + 4j
print(z.real) # 3.0
print(z.imag) # 4.0
print(abs(z)) # 5.0(模长)
4.2.4 数字类型对比
| 类型 | 示例 | 不可变 | 精度 |
|---|---|---|---|
| int | 42, 0xFF | ✅ | 无限 |
| float | 3.14, 1e-3 | ✅ | 64 位双精度 |
| complex | 1+2j | ✅ | 双精度 |
| Decimal | Decimal("3.14") | ✅ | 任意精度 |
4.2.5 数学运算
# 基本运算
print(7 + 3) # 10 加法
print(7 - 3) # 4 减法
print(7 * 3) # 21 乘法
print(7 / 3) # 2.3333... 真除法
print(7 // 3) # 2 整除(向下取整)
print(7 % 3) # 1 取余
print(7 ** 3) # 343 幂运算
# 注意负数整除
print(-7 // 3) # -3(向下取整,不是 -2)
# 内置数学函数
print(abs(-5)) # 5
print(round(3.14159, 2)) # 3.14
print(min(3, 1, 4)) # 1
print(max(3, 1, 4)) # 4
print(sum([1, 2, 3])) # 6
print(divmod(17, 5)) # (3, 2)
4.2.6 math 模块
import math
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
print(math.sqrt(16)) # 4.0
print(math.ceil(3.2)) # 4
print(math.floor(3.8))# 3
print(math.log(100, 10)) # 2.0
print(math.factorial(5)) # 120
print(math.gcd(12, 8)) # 4
4.3 字符串(str)
4.3.1 创建字符串
# 单引号和双引号等价
s1 = 'Hello'
s2 = "Hello"
# 三引号:多行字符串
s3 = """这是
一个
多行字符串"""
# 转义字符
tab = "a\tb" # a b
newline = "a\nb" # 换行
backslash = "a\\b" # a\b
quote = "He said \"hi\"" # He said "hi"
# 原始字符串(忽略转义)
path = r"C:\Users\docs\new"
pattern = r"\d+\.\d+"
4.3.2 字符串操作
s = "Hello, Python!"
# 索引(从 0 开始)
print(s[0]) # H
print(s[-1]) # !
# 切片 [start:stop:step]
print(s[0:5]) # Hello
print(s[7:]) # Python!
print(s[::-1]) # !nohtyP ,olleH
# 长度
print(len(s)) # 14
# 查找
print(s.find("Python")) # 7
print("Python" in s) # True
print(s.startswith("Hello")) # True
print(s.endswith("!")) # True
# 替换
print(s.replace("Python", "World")) # Hello, World!
# 分割与拼接
words = "one,two,three".split(",")
print(words) # ['one', 'two', 'three']
print("-".join(words)) # one-two-three
# 大小写
print("hello".upper()) # HELLO
print("HELLO".lower()) # hello
print("hello world".title()) # Hello World
print("hello world".capitalize()) # Hello world
# 去除空白
print(" hello ".strip()) # hello
print(" hello ".lstrip()) # hello
print(" hello ".rstrip()) # hello
# 判断
print("abc123".isalnum()) # True
print("abc".isalpha()) # True
print("123".isdigit()) # True
print(" ".isspace()) # True
4.3.3 字符串是不可变的
s = "Hello"
# s[0] = "h" # ❌ TypeError: 'str' object does not support item assignment
# 要修改,创建新字符串
s = "h" + s[1:] # "hello"
4.4 布尔值(bool)
4.4.1 基本用法
is_active = True
is_deleted = False
# 布尔运算
print(True and False) # False
print(True or False) # True
print(not True) # False
# 比较运算
print(5 > 3) # True
print(5 == 3) # False
print(5 != 3) # True
print(5 >= 5) # True
4.4.2 Truthy 和 Falsy
以下值在布尔上下文中为 False:
| 类型 | Falsy 值 |
|---|---|
| bool | False |
| 数字 | 0, 0.0, 0j |
| 字符串 | "" (空字符串) |
| 容器 | [], (), {}, set() |
| 特殊 | None |
其他所有值都为 True:
# 真值测试
bool(0) # False
bool(42) # True
bool("") # False
bool("hello") # True
bool([]) # False
bool([1, 2]) # True
bool(None) # False
# Pythonic 写法
if my_list: # 而不是 if len(my_list) > 0:
process(my_list)
if not name: # 而不是 if name == "":
raise ValueError("名字不能为空")
4.4.3 短路求值
# and:第一个为 False 则不计算第二个
x = None
result = x and x.name # None,不会报错
# or:第一个为 True 则不计算第二个
default = user_input or "default_value"
4.4.4 bool 是 int 的子类
print(isinstance(True, int)) # True
print(True + True) # 2
print(True * 10) # 10
print(sum([True, False, True, True])) # 3
4.5 None
# None 是 NoneType 的唯一实例
x = None
print(type(x)) # <class 'NoneType'>
# 判断是否为 None,使用 is 而非 ==
if x is None:
print("x 是 None")
# ✅ 正确
if x is None: ...
if x is not None: ...
# ❌ 不推荐(虽然也能工作)
if x == None: ...
4.6 类型转换
4.6.1 隐式转换
# 数字运算时,int → float
result = 3 + 2.5 # float: 5.5
# bool → int
result = True + 1 # int: 2
4.6.2 显式转换
# int()
int("42") # 42
int(3.9) # 3(截断,不四舍五入)
int(True) # 1
# float()
float("3.14") # 3.14
float(42) # 42.0
float("1e3") # 1000.0
# str()
str(42) # "42"
str(3.14) # "3.14"
str(True) # "True"
str(None) # "None"
# bool()
bool(0) # False
bool("") # False
bool([]) # False
bool(1) # True
4.6.3 类型检查
x = 42
# type() 精确检查
type(x) is int # True
type(x) is float # False
# isinstance() 支持继承检查
isinstance(x, int) # True
isinstance(x, (int, float)) # True(检查多个类型)
# ⚠️ 区别
class MyInt(int): pass
x = MyInt(42)
type(x) is int # False(精确匹配)
isinstance(x, int) # True(考虑继承)
4.7 动态类型
4.7.1 Python 的类型系统
Python 是动态类型、强类型语言:
# 动态类型:变量可以重新绑定到不同类型
x = 42 # int
x = "hello" # str(合法)
# 强类型:不同类型不能隐式转换
# "hello" + 42 # ❌ TypeError(不是自动转换为 "hello42")
"hello" + str(42) # ✅ "hello42"(显式转换)
4.7.2 对象的可变性
# 不可变类型(immutable)
x = 42
y = x
x = 100
print(y) # 42(y 不受影响)
# 可变类型(mutable)
a = [1, 2, 3]
b = a
a.append(4)
print(b) # [1, 2, 3, 4](b 也变了!因为 a 和 b 引用同一对象)
# 复制可变对象
import copy
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
| 类型 | 可变性 |
|---|---|
| int, float, complex | 不可变 |
| str | 不可变 |
| tuple | 不可变 |
| frozenset | 不可变 |
| bytes | 不可变 |
| list | 可变 |
| dict | 可变 |
| set | 可变 |
| bytearray | 可变 |
4.8 类型注解(Type Hints)
# 变量注解
name: str = "Alice"
age: int = 30
scores: list[int] = [90, 85, 92]
# 函数注解
def greet(name: str, times: int = 1) -> str:
return (f"Hello, {name}! " * times).strip()
# Optional:可能为 None
from typing import Optional
def find_user(user_id: int) -> Optional[dict]:
if user_id > 0:
return {"id": user_id, "name": "Alice"}
return None
🔴 注意:类型注解不强制执行,仅用于工具检查和文档。
4.9 注意事项
🔴 注意:
- 浮点数比较不要用
==,使用math.isclose() - 可变对象的引用共享可能导致意外修改
None判断用is/is not,不要用==bool是int的子类,True == 1,False == 0
💡 提示:
- 使用下划线提高大数字的可读性:
1_000_000 - 使用
f-string格式化字符串(下一章详述) - 使用
isinstance()而非type()进行类型检查 - 使用
Decimal处理金融计算
📌 业务场景:
from decimal import Decimal, ROUND_HALF_UP
def calculate_price(price: float, quantity: int, discount: float = 0.0) -> Decimal:
"""计算订单总价(精确到分)。"""
unit = Decimal(str(price))
qty = Decimal(str(quantity))
disc = Decimal(str(discount))
total = unit * qty * (1 - disc)
return total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
print(calculate_price(9.99, 3, 0.1)) # 26.97
4.10 扩展阅读
- Built-in Types - Python 文档
- PEP 484 - Type Hints
- 浮点数精度问题
- decimal 模块文档
- 《流畅的 Python》第 1 章:Python 数据模型