强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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
区分大小写nameName
避免使用保留字不能用 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 数字类型对比

类型示例不可变精度
int42, 0xFF无限
float3.14, 1e-364 位双精度
complex1+2j双精度
DecimalDecimal("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 值
boolFalse
数字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,不要用 ==
  • boolint 的子类,True == 1False == 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 扩展阅读