Skip to content

Python 控制流程详解 - 深度教程 ​

目录 ​


条件语句 ​

if 语句基础 ​

python
# 基本 if 语句
age = 18
if age >= 18:
    print("你是成年人")

# if-else
score = 85
if score >= 60:
    print("及格")
else:
    print("不及格")

# if-elif-else(多分支)
score = 85
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
elif score >= 60:
    grade = 'D'
else:
    grade = 'F'
print(f"成绩等级:{grade}")

条件表达式 ​

布尔值和真值测试 ​

python
# 假值(Falsy):
# False, None, 0, 0.0, "", [], {}, set()

# 真值测试
if []:
    print("不会执行")

if [1, 2, 3]:
    print("会执行")

# 常见模式
name = input("Enter name: ")
if name:  # 检查是否为空字符串
    print(f"Hello, {name}")
else:
    print("Name cannot be empty")

# 数字
num = 0
if num:
    print("不会执行")
if num == 0:
    print("会执行")

逻辑运算符 ​

python
# and、or、not
age = 20
has_license = True

# and:所有条件都为真
if age >= 18 and has_license:
    print("可以开车")

# or:至少一个条件为真
is_weekend = True
is_holiday = False
if is_weekend or is_holiday:
    print("可以休息")

# not:取反
is_raining = False
if not is_raining:
    print("不需要带伞")

# 组合使用
if (age >= 18 and has_license) or age >= 21:
    print("满足条件")

# 短路求值
def expensive_check():
    print("执行了昂贵的检查")
    return True

# expensive_check() 不会被调用
if False and expensive_check():
    pass

# expensive_check() 不会被调用
if True or expensive_check():
    pass

比较链 ​

python
# Python 支持链式比较
x = 5
if 0 < x < 10:
    print("x 在 0 和 10 之间")

# 等价于
if 0 < x and x < 10:
    print("x 在 0 和 10 之间")

# 更多例子
score = 85
if 80 <= score <= 90:
    print("成绩良好")

# 可以链接多个比较
if 1 < x < 5 < y < 10:
    print("满足所有条件")

三元运算符(条件表达式) ​

python
# 语法:value_if_true if condition else value_if_false

age = 20
status = "成年人" if age >= 18 else "未成年人"

# 嵌套三元运算符(不推荐,可读性差)
score = 85
grade = 'A' if score >= 90 else ('B' if score >= 80 else 'C')

# 更好的写法
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
else:
    grade = 'C'

# 实际应用
numbers = [1, 2, 3, 4, 5]
result = [x * 2 if x % 2 == 0 else x for x in numbers]
# [1, 4, 3, 8, 5]

match-case 语句(Python 3.10+) ​

python
# 类似其他语言的 switch-case

def http_status(status):
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Internal Server Error"
        case _:  # 默认情况
            return "Unknown"

# 模式匹配
def process_command(command):
    match command.split():
        case ["quit"]:
            print("退出程序")
        case ["load", filename]:
            print(f"加载文件:{filename}")
        case ["save", filename]:
            print(f"保存文件:{filename}")
        case _:
            print("未知命令")

# 更复杂的模式
def describe_point(point):
    match point:
        case (0, 0):
            print("原点")
        case (0, y):
            print(f"Y轴上的点:{y}")
        case (x, 0):
            print(f"X轴上的点:{x}")
        case (x, y):
            print(f"点:({x}, {y})")

# 使用 guards
def categorize_number(num):
    match num:
        case n if n < 0:
            print("负数")
        case 0:
            print("零")
        case n if n > 0:
            print("正数")

循环语句 ​

for 循环 ​

基本用法 ​

python
# 遍历列表
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
    print(fruit)

# 遍历字符串
for char in "Python":
    print(char)

# 遍历字典
person = {"name": "Alice", "age": 25, "city": "Beijing"}

# 遍历键
for key in person:
    print(key)

# 遍历值
for value in person.values():
    print(value)

# 遍历键值对
for key, value in person.items():
    print(f"{key}: {value}")

range() 函数 ​

python
# range(stop)
for i in range(5):
    print(i)  # 0, 1, 2, 3, 4

# range(start, stop)
for i in range(1, 6):
    print(i)  # 1, 2, 3, 4, 5

# range(start, stop, step)
for i in range(0, 10, 2):
    print(i)  # 0, 2, 4, 6, 8

# 反向
for i in range(10, 0, -1):
    print(i)  # 10, 9, 8, ..., 1

# 负数范围
for i in range(-5, 0):
    print(i)  # -5, -4, -3, -2, -1

# range 是惰性求值(节省内存)
r = range(1000000)  # 不会立即创建所有数字
print(list(range(5)))  # [0, 1, 2, 3, 4]

enumerate() - 带索引遍历 ​

python
fruits = ["apple", "banana", "orange"]

# 获取索引和值
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")
# 0: apple
# 1: banana
# 2: orange

# 指定起始索引
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}: {fruit}")
# 1: apple
# 2: banana
# 3: orange

# 实际应用:查找元素
def find_all_indices(lst, value):
    return [i for i, x in enumerate(lst) if x == value]

numbers = [1, 2, 3, 2, 1]
print(find_all_indices(numbers, 2))  # [1, 3]

zip() - 并行遍历 ​

python
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["Beijing", "Shanghai", "Shenzhen"]

# 并行遍历多个序列
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, 来自{city}")

# zip 以最短序列为准
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c']
for num, letter in zip(list1, list2):
    print(num, letter)
# 1 a
# 2 b
# 3 c

# 创建字典
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Beijing']
person = dict(zip(keys, values))
# {'name': 'Alice', 'age': 25, 'city': 'Beijing'}

# 解压(unzip)
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers, letters = zip(*pairs)
# numbers = (1, 2, 3)
# letters = ('a', 'b', 'c')

列表推导式(复习) ​

python
# 基本形式
squares = [x**2 for x in range(10)]

# 带条件
evens = [x for x in range(20) if x % 2 == 0]

# 带 if-else
result = [x if x % 2 == 0 else -x for x in range(10)]

# 嵌套循环
matrix = [[i * 3 + j for j in range(3)] for i in range(3)]
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

# 过滤和转换
words = ["hello", "world", "python"]
upper_long_words = [w.upper() for w in words if len(w) > 5]
# ['PYTHON']

while 循环 ​

基本用法 ​

python
# 基本 while 循环
count = 0
while count < 5:
    print(count)
    count += 1

# 无限循环
while True:
    response = input("继续吗?(y/n): ")
    if response.lower() == 'n':
        break

# 条件变化
password = ""
while password != "123456":
    password = input("输入密码: ")
print("密码正确!")

while-else ​

python
# else 子句在循环正常结束时执行(没有 break)
count = 0
while count < 5:
    print(count)
    count += 1
else:
    print("循环正常结束")

# 使用 break 时不执行 else
count = 0
while count < 10:
    if count == 5:
        break
    count += 1
else:
    print("不会执行")  # break 导致跳过

实际应用 ​

python
# 输入验证
def get_positive_number():
    while True:
        try:
            num = int(input("请输入正整数: "))
            if num > 0:
                return num
            else:
                print("必须是正整数")
        except ValueError:
            print("请输入有效的数字")

# 菜单系统
def menu():
    while True:
        print("\n菜单:")
        print("1. 选项 1")
        print("2. 选项 2")
        print("3. 退出")
        
        choice = input("请选择: ")
        
        if choice == '1':
            print("执行选项 1")
        elif choice == '2':
            print("执行选项 2")
        elif choice == '3':
            break
        else:
            print("无效选择")

# 游戏循环
def game_loop():
    running = True
    score = 0
    
    while running:
        # 游戏逻辑
        action = input("动作 (attack/defend/quit): ")
        
        if action == 'attack':
            score += 10
        elif action == 'defend':
            score += 5
        elif action == 'quit':
            running = False
        
        print(f"当前分数: {score}")

循环控制 ​

break 语句 ​

python
# break:立即退出最内层循环
for i in range(10):
    if i == 5:
        break
    print(i)
# 输出:0, 1, 2, 3, 4

# 查找元素
numbers = [1, 3, 5, 7, 9, 2, 4]
for num in numbers:
    if num % 2 == 0:
        print(f"找到第一个偶数: {num}")
        break

# 嵌套循环中的 break(只退出内层)
for i in range(3):
    for j in range(3):
        if j == 1:
            break
        print(f"i={i}, j={j}")
# i=0, j=0
# i=1, j=0
# i=2, j=0

continue 语句 ​

python
# continue:跳过本次迭代,继续下一次
for i in range(10):
    if i % 2 == 0:
        continue  # 跳过偶数
    print(i)
# 输出:1, 3, 5, 7, 9

# 跳过特定条件
words = ["hello", "world", "", "python", ""]
for word in words:
    if not word:  # 跳过空字符串
        continue
    print(word.upper())

# 数据过滤
numbers = [1, -2, 3, -4, 5, -6]
positive_sum = 0
for num in numbers:
    if num < 0:
        continue
    positive_sum += num
print(positive_sum)  # 9

pass 语句 ​

python
# pass:空操作,占位符
for i in range(5):
    if i == 2:
        pass  # 什么也不做
    print(i)

# 用于未实现的函数
def todo_function():
    pass  # 稍后实现

# 用于类定义
class EmptyClass:
    pass

# 实际应用:异常处理的占位
try:
    risky_operation()
except SpecificError:
    pass  # 忽略这个特定错误
except Exception as e:
    handle_error(e)

else 子句 ​

python
# for-else
for i in range(5):
    if i == 10:
        break
else:
    print("循环正常结束,没有 break")

# 实际应用:搜索
def find_user(users, target_name):
    for user in users:
        if user['name'] == target_name:
            return user
            break
    else:
        return None  # 没找到

# while-else
attempts = 0
max_attempts = 3

while attempts < max_attempts:
    password = input("输入密码: ")
    if password == "secret":
        print("登录成功")
        break
    attempts += 1
else:
    print("尝试次数过多,账户锁定")

异常处理 ​

try-except 基础 ​

python
# 基本异常处理
try:
    x = int(input("输入数字: "))
    result = 10 / x
    print(f"结果: {result}")
except ValueError:
    print("请输入有效的数字")
except ZeroDivisionError:
    print("不能除以零")

# 捕获多个异常
try:
    # 可能出错的代码
    pass
except (ValueError, TypeError):
    print("值错误或类型错误")

# 捕获所有异常
try:
    risky_operation()
except Exception as e:
    print(f"发生错误: {e}")

异常信息 ​

python
# 获取异常详情
try:
    x = 10 / 0
except ZeroDivisionError as e:
    print(f"错误类型: {type(e).__name__}")
    print(f"错误消息: {e}")
    print(f"错误参数: {e.args}")

# 打印完整的错误追踪
import traceback

try:
    risky_operation()
except Exception:
    traceback.print_exc()

try-except-else-finally ​

python
# 完整结构
try:
    # 可能出错的代码
    file = open("data.txt", "r")
    data = file.read()
except FileNotFoundError:
    # 文件不存在时执行
    print("文件未找到")
except Exception as e:
    # 其他错误
    print(f"发生错误: {e}")
else:
    # 没有异常时执行
    print("文件读取成功")
    process_data(data)
finally:
    # 总是执行(清理操作)
    if 'file' in locals():
        file.close()
    print("清理完成")

抛出异常 ​

python
# raise 语句
def divide(a, b):
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

try:
    result = divide(10, 0)
except ValueError as e:
    print(f"错误: {e}")

# 重新抛出异常
try:
    risky_operation()
except Exception as e:
    log_error(e)
    raise  # 重新抛出相同的异常

# 抛出不同的异常
try:
    data = fetch_data()
except NetworkError as e:
    raise DataError("数据获取失败") from e

自定义异常 ​

python
# 定义自定义异常类
class InvalidAgeError(Exception):
    """年龄无效异常"""
    pass

class NegativeAgeError(InvalidAgeError):
    """年龄为负数异常"""
    pass

# 使用自定义异常
def set_age(age):
    if age < 0:
        raise NegativeAgeError(f"年龄不能为负数: {age}")
    if age > 150:
        raise InvalidAgeError(f"年龄不合理: {age}")
    return age

try:
    set_age(-5)
except NegativeAgeError as e:
    print(f"错误: {e}")
except InvalidAgeError as e:
    print(f"错误: {e}")

常见内置异常 ​

python
# ValueError:值错误
int("abc")  # ValueError

# TypeError:类型错误
"2" + 2  # TypeError

# KeyError:键错误
d = {"a": 1}
d["b"]  # KeyError

# IndexError:索引错误
lst = [1, 2, 3]
lst[10]  # IndexError

# AttributeError:属性错误
x = 5
x.append(1)  # AttributeError

# FileNotFoundError:文件未找到
open("nonexistent.txt")  # FileNotFoundError

# ZeroDivisionError:除零错误
10 / 0  # ZeroDivisionError

# ImportError:导入错误
import nonexistent_module  # ImportError

# StopIteration:迭代器耗尽
it = iter([1, 2])
next(it)
next(it)
next(it)  # StopIteration

上下文管理器 ​

with 语句 ​

python
# 基本用法:文件操作
with open("file.txt", "r") as f:
    content = f.read()
# 文件自动关闭,即使发生异常

# 等价于
f = open("file.txt", "r")
try:
    content = f.read()
finally:
    f.close()

# 多个上下文管理器
with open("input.txt") as infile, open("output.txt", "w") as outfile:
    for line in infile:
        outfile.write(line.upper())

自定义上下文管理器 ​

使用类 ​

python
class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
        self.file = None
    
    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        # 返回 True 表示抑制异常
        # 返回 False 或 None 表示传播异常
        return False

# 使用
with FileManager("test.txt", "w") as f:
    f.write("Hello")

使用装饰器 ​

python
from contextlib import contextmanager

@contextmanager
def file_manager(filename, mode):
    try:
        f = open(filename, mode)
        yield f
    finally:
        f.close()

# 使用
with file_manager("test.txt", "w") as f:
    f.write("Hello")

常用上下文管理器 ​

python
# 1. 文件操作
with open("file.txt", "r") as f:
    data = f.read()

# 2. 线程锁
import threading
lock = threading.Lock()

with lock:
    # 临界区代码
    shared_resource += 1

# 3. 数据库连接
import sqlite3

with sqlite3.connect("database.db") as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")

# 4. 改变目录
import os
from contextlib import contextmanager

@contextmanager
def change_dir(path):
    old_dir = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(old_dir)

with change_dir("/tmp"):
    # 在 /tmp 目录中操作
    pass
# 自动恢复原目录

# 5. 临时设置
@contextmanager
def temporary_setting(name, value):
    old_value = getattr(config, name)
    setattr(config, name, value)
    try:
        yield
    finally:
        setattr(config, name, old_value)

实战案例 ​

案例 1:猜数字游戏(完整版) ​

python
import random

def guess_number_game():
    """完整的猜数字游戏"""
    print("=== 猜数字游戏 ===")
    print("我想了一个 1-100 之间的数字")
    
    secret = random.randint(1, 100)
    attempts = 0
    max_attempts = 10
    
    while attempts < max_attempts:
        try:
            guess = int(input(f"\n第 {attempts + 1} 次猜测: "))
            
            if guess < 1 or guess > 100:
                print("请输入 1-100 之间的数字!")
                continue
            
            attempts += 1
            
            if guess < secret:
                print("太小了!")
            elif guess > secret:
                print("太大了!")
            else:
                print(f"🎉 恭喜你猜对了!")
                print(f"你用了 {attempts} 次")
                break
        
        except ValueError:
            print("请输入有效的数字!")
    else:
        print(f"\n游戏结束!答案是 {secret}")

guess_number_game()

案例 2:待办事项管理器 ​

python
def todo_manager():
    """待办事项管理器"""
    todos = []
    
    while True:
        print("\n=== 待办事项 ===")
        print("1. 查看任务")
        print("2. 添加任务")
        print("3. 完成任务")
        print("4. 删除任务")
        print("5. 退出")
        
        try:
            choice = input("\n请选择操作: ")
            
            if choice == '1':
                if not todos:
                    print("没有任务")
                else:
                    for i, task in enumerate(todos, 1):
                        status = "✓" if task['done'] else " "
                        print(f"{i}. [{status}] {task['title']}")
            
            elif choice == '2':
                title = input("任务标题: ")
                if title:
                    todos.append({'title': title, 'done': False})
                    print("任务已添加!")
                else:
                    print("标题不能为空")
            
            elif choice == '3':
                if not todos:
                    print("没有任务")
                    continue
                
                try:
                    index = int(input("完成哪个任务?: ")) - 1
                    if 0 <= index < len(todos):
                        todos[index]['done'] = True
                        print("任务已完成!")
                    else:
                        print("无效的任务编号")
                except ValueError:
                    print("请输入有效的数字")
            
            elif choice == '4':
                if not todos:
                    print("没有任务")
                    continue
                
                try:
                    index = int(input("删除哪个任务?: ")) - 1
                    if 0 <= index < len(todos):
                        removed = todos.pop(index)
                        print(f"已删除: {removed['title']}")
                    else:
                        print("无效的任务编号")
                except ValueError:
                    print("请输入有效的数字")
            
            elif choice == '5':
                print("再见!")
                break
            
            else:
                print("无效的选择")
        
        except KeyboardInterrupt:
            print("\n\n程序被中断")
            break

todo_manager()

案例 3:文件处理器 ​

python
def process_log_file(filename):
    """处理日志文件,统计错误信息"""
    error_count = {}
    line_number = 0
    
    try:
        with open(filename, 'r') as f:
            for line in f:
                line_number += 1
                
                if 'ERROR' in line:
                    # 提取错误类型
                    try:
                        error_type = line.split('ERROR:')[1].split()[0]
                        error_count[error_type] = error_count.get(error_type, 0) + 1
                    except IndexError:
                        print(f"第 {line_number} 行格式错误")
                        continue
    
    except FileNotFoundError:
        print(f"文件 {filename} 不存在")
        return None
    except PermissionError:
        print(f"没有权限读取文件 {filename}")
        return None
    except Exception as e:
        print(f"处理文件时发生错误: {e}")
        return None
    else:
        print(f"\n成功处理 {line_number} 行")
        return error_count
    finally:
        print("文件处理完成")

# 使用
result = process_log_file("app.log")
if result:
    print("\n错误统计:")
    for error_type, count in result.items():
        print(f"{error_type}: {count}")

案例 4:用户输入验证器 ​

python
def get_validated_input():
    """获取并验证用户输入"""
    
    # 验证邮箱
    while True:
        email = input("输入邮箱: ")
        if '@' in email and '.' in email.split('@')[1]:
            break
        print("邮箱格式不正确")
    
    # 验证年龄
    while True:
        try:
            age = int(input("输入年龄: "))
            if 0 < age < 150:
                break
            print("年龄必须在 1-150 之间")
        except ValueError:
            print("请输入有效的数字")
    
    # 验证密码
    while True:
        password = input("输入密码(至少6位): ")
        if len(password) >= 6:
            confirm = input("确认密码: ")
            if password == confirm:
                break
            print("两次密码不一致")
        else:
            print("密码至少6位")
    
    return {
        'email': email,
        'age': age,
        'password': password
    }

user_data = get_validated_input()
print(f"\n注册成功!邮箱: {user_data['email']}")

练习题 ​

练习 1:FizzBuzz ​

python
# 打印 1-100,但:
# - 3的倍数打印 "Fizz"
# - 5的倍数打印 "Buzz"
# - 15的倍数打印 "FizzBuzz"
# - 其他打印数字本身

# 你的代码

练习 2:质数判断 ​

python
def is_prime(n):
    """判断一个数是否为质数"""
    # 你的代码
    pass

练习 3:列表去重(保持顺序) ​

python
def remove_duplicates(lst):
    """去除列表中的重复元素,保持原始顺序"""
    # 你的代码
    pass

学习检查清单 ​

  • [ ] 理解 if-elif-else 的执行流程
  • [ ] 掌握各种循环方式(for, while)
  • [ ] 熟练使用 break、continue、pass
  • [ ] 理解异常处理机制
  • [ ] 会创建和使用上下文管理器
  • [ ] 能够处理嵌套循环和复杂控制流
  • [ ] 完成所有练习题

继续学习:05_函数深入.md