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=0continue 语句
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) # 9pass 语句
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
