Python & AI Tutorials Logo
Python 编程

8. 使用 if 语句做决策

在我们目前写过的程序中,Python 会从上到下执行每一行代码,一条语句接着一条语句地运行。但真实世界的程序需要做决策——根据不同条件执行不同的代码。我们是否应该显示一条错误消息?是否应该计算折扣?是否应该再次请求输入?答案取决于具体情况。

条件语句 (conditional statements) 让你的程序能够做出这些决策。它们允许 Python 仅在特定条件为真时执行某些代码块,否则就跳过它们。本章将介绍 Python 的 if 语句及其变体,它们构成了程序中决策能力的基础。

通过掌握条件语句,你将能够编写能对用户输入做出智能响应的程序,恰当地处理不同场景,并解决需要逻辑推理的问题。

8.1) 简单的 if 语句

Python 中最基本的决策形式是 简单 if 语句 (simple if statement)。它告诉 Python:“如果这个条件为真,就执行这段代码块。否则跳过它并继续。”

8.1.1) if 语句的结构

下面是 if 语句的基本语法:

python
if condition:
    # 当 condition 为 True 时要执行的代码
    statement1
    statement2
    # ... 更多语句

我们来分解一下每个部分:

  1. if 关键字:这会开始一个条件语句
  2. 条件:一个会计算为 TrueFalse 的布尔表达式(来自第 7 章)
  3. 冒号 (:):这是必需的,用来标记条件行的结束
  4. 缩进的代码块:所有缩进在 if 之下的语句,只有当条件为 True 时才会执行

缩进在 Python 中至关重要。 缩进的行构成了属于 if 语句的 代码块 (code block)。Python 使用缩进(通常为 4 个空格)来确定哪些语句属于条件块的一部分。

下面是一个简单示例:

python
# temperature_check.py
temperature = 30
 
if temperature > 25:
    print("It's a warm day!")
    print("Consider wearing light clothing.")
 
print("Have a great day!")  # 这行总会执行

Output:

It's a warm day!
Consider wearing light clothing.
Have a great day!

在这个示例中:

  • 条件 temperature > 25 的计算结果为 True(因为 30 > 25)
  • 两条缩进的 print() 语句会执行,因为它们是 if 块的一部分
  • 最后一条 print() 语句总会执行,因为它没有缩进——它不是 if 块的一部分

现在让我们看看条件为 False 时会发生什么:

python
# temperature_check_cool.py
temperature = 18
 
if temperature > 25:
    print("It's a warm day!")
    print("Consider wearing light clothing.")
 
print("Have a great day!")  # 这行总会执行

Output:

Have a great day!

这一次:

  • 条件 temperature > 25 的计算结果为 False(因为 18 并不大于 25)
  • 两条缩进语句会被完全跳过
  • 只有最后的 print() 会执行,因为它在 if 块之外

开始

条件为 True 吗?

执行缩进的代码块

跳过缩进的代码块

继续执行程序的其余部分

结束

8.1.2) 使用第 7 章中的条件

第 7 章中的任何布尔表达式都可以用作 if 语句中的条件。这包括:

比较运算符:

python
# voting_eligibility.py
age = 16
 
if age >= 18:
    print("You are eligible to vote.")
# 因为 16 >= 18 为 False,所以不会打印任何内容
 
score = 85
 
if score >= 60:
    print("You passed the exam!")  # Output: You passed the exam!

使用 innot in 的成员测试:

python
# user_access.py
username = "alice"
banned_users = ["bob", "charlie", "dave"]
 
if username not in banned_users:
    print(f"Welcome, {username}!")  # Output: Welcome, alice!
 
favorite_color = "blue"
 
if "u" in favorite_color:
    print("Your favorite color contains the letter 'u'.")  # Output: Your favorite color contains the letter 'u'.

直接使用布尔值:

python
# weather_check.py
is_raining = True
 
if is_raining:
    print("Don't forget your umbrella!")  # Output: Don't forget your umbrella!

真值与假值 (truthiness and falsiness)(来自第 7.4 节):

python
# name_input.py
user_input = input("Enter your name: ")
 
if user_input:  # 空字符串是假值,非空字符串是真值
    print(f"Hello, {user_input}!")
else:
    print("You didn't enter a name.")

8.1.3) 在 if 块中包含多条语句

你可以在 if 块中包含任意多条语句。if 行下面所有缩进的语句都属于该代码块:

python
# bank_withdrawal.py
balance = 1500
withdrawal = 200
 
if withdrawal <= balance:
    balance = balance - withdrawal  # 从 balance 中减去 withdrawal
    print(f"Withdrawal successful!")
    print(f"Your new balance is: ${balance}")
    print("Thank you for your transaction.")
 
print("Transaction complete.")  # 总会执行

Output:

Withdrawal successful!
Your new balance is: $1300
Thank you for your transaction.
Transaction complete.

四条语句都会执行,因为 withdrawal <= balanceTrue。如果我们把取款金额改成 2000:

python
# bank_withdrawal_insufficient.py
balance = 1500
withdrawal = 2000
 
if withdrawal <= balance:
    balance = balance - withdrawal
    print(f"Withdrawal successful!")
    print(f"Your new balance is: ${balance}")
    print("Thank you for your transaction.")
 
print("Transaction complete.")  # 总会执行

Output:

Transaction complete.

现在由于条件为 False,所有缩进语句都不会执行。余额仍保持为 1500,不会改变。

8.2) 使用 if-else 进行二选一

很多时候你需要在两个备选项之间做选择:如果条件为真就执行一段代码块,如果为假则执行另一段代码块。if-else 语句 (if-else statement) 用于处理这种二选一的决策。

8.2.1) if-else 的结构

语法如下:

python
if condition:
    # 当 condition 为 True 时要执行的代码
    statement1
    statement2
else:
    # 当 condition 为 False 时要执行的代码
    statement3
    statement4

else 子句提供了一条替代路径。两个代码块中恰好会执行一个——不会两者都执行,也不会两者都不执行。

开始

条件为 True 吗?

执行 if 块

执行 else 块

继续执行程序的其余部分

结束

我们来看一个实际例子:

python
# age_verification.py
age = int(input("Enter your age: "))
 
if age >= 18:
    print("You are an adult.")
    print("You can vote in elections.")
else:
    print("You are a minor.")
    print("You cannot vote yet.")
 
print("Thank you for providing your age.")

如果你输入 25:

You are an adult.
You can vote in elections.
Thank you for providing your age.

如果你输入 15:

You are a minor.
You cannot vote yet.
Thank you for providing your age.

注意两个代码块中恰好会执行一个,取决于条件。最后的 print() 语句总会执行,因为它在两个代码块之外。

8.2.2) 做二元决策

if-else 非常适合只有两种可能结果的二元决策:

python
# even_odd_checker.py
number = int(input("Enter a number: "))
 
if number % 2 == 0:
    print(f"{number} is even.")
else:
    print(f"{number} is odd.")
python
# password_verification.py
stored_password = "python123"
entered_password = input("Enter password: ")
 
if entered_password == stored_password:
    print("Access granted.")
    print("Welcome to the system!")
else:
    print("Access denied.")
    print("Incorrect password.")

8.3) 使用 if-elif-else 处理多个选择

现实世界的决策往往不止两个选项。我们应该收取标准运费、加急运费还是隔夜运费?成绩是 A、B、C、D 还是 F?if-elif-else 链 (if-elif-else chain) 用于处理多个互斥的备选项。

8.3.1) if-elif-else 的结构

语法如下:

python
if condition1:
    # 当 condition1 为 True 时执行
    block1
elif condition2:
    # 当 condition1 为 False 且 condition2 为 True 时执行
    block2
elif condition3:
    # 当 condition1 和 condition2 都为 False,且 condition3 为 True 时执行
    block3
else:
    # 当所有条件都为 False 时执行
    block4

关于 if-elif-else 链的关键点:

  1. elif 是 “else if” 的缩写:它提供了额外要检查的条件
  2. 顺序很重要:Python 从上到下检查条件
  3. 先匹配者生效:一旦某个条件为 True,对应代码块就会执行,其余条件会被跳过
  4. 恰好执行一个代码块:链中最多只有一个代码块会运行
  5. else 是可选的:它会捕获前面条件未处理的所有情况

开始

condition1 为 True 吗?

执行 block1

condition2 为 True 吗?

执行 block2

condition3 为 True 吗?

执行 block3

执行 else 块

继续执行程序的其余部分

结束

我们来看一个实际例子:

python
# grade_calculator.py
score = int(input("Enter your exam score (0-100): "))
 
if score >= 90:
    grade = "A"
    print("Excellent work!")
elif score >= 80:
    grade = "B"
    print("Good job!")
elif score >= 70:
    grade = "C"
    print("Satisfactory.")
elif score >= 60:
    grade = "D"
    print("You passed, but consider reviewing the material.")
else:
    grade = "F"
    print("Unfortunately, you did not pass.")
 
print(f"Your grade is: {grade}")

如果你输入 85:

Good job!
Your grade is: B

我们来追踪一下发生了什么:

  1. 检查 score >= 90:False(85 不 >= 90),所以跳过该代码块
  2. 检查 score >= 80:True(85 >= 80),所以执行该代码块
  3. 因为找到了匹配项,跳过所有剩余的 elifelse 代码块

如果你输入 55:

Unfortunately, you did not pass.
Your grade is: F

所有条件都为 False,因此会执行 else 块。

8.3.2) 为什么 elif 链中的顺序很重要

条件的顺序至关重要,因为 Python 一旦找到 True 条件就会停止继续检查。考虑下面这个错误的评分系统:

python
# 顺序不正确 - 不要这样做!
score = 85
 
if score >= 60:  # 这里会先匹配!
    grade = "D"
elif score >= 70:
    grade = "C"
elif score >= 80:
    grade = "B"
elif score >= 90:
    grade = "A"
else:
    grade = "F"
 
print(f"Your grade is: {grade}")  # Output: Your grade is: D

这会给出错误的结果!85 分应该是 B,但它得到了 D,因为先检查了 score >= 60 并且它为 True。Python 永远不会检查到 score >= 80 这个条件。

始终将条件从最具体到最不具体进行排序

python
# 正确的顺序
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"Your grade is: {grade}")  # Output: Your grade is: B

8.3.3) 使用不带 else 的 elif

else 子句是可选的。有时你只想处理特定情况,而对其他情况什么都不做:

python
# weekend_checker.py
day = input("Enter a day of the week: ").lower()
 
if day == "saturday" or day == "sunday":
    print("It's the weekend! Time to relax.")
elif day == "friday":
    print("It's Friday! The weekend is almost here.")
elif day in ["monday", "tuesday", "wednesday", "thursday"]:
    print("It's a weekday. Time to work or study.")
# 没有 else 子句——如果都不匹配,就什么也不发生
 
print("Have a great day!")

如果你输入 "holiday":

Have a great day!

没有条件匹配,并且没有 else 子句,所以只有最后的 print() 会执行。

8.4) 嵌套 if 语句

有时你需要在一个决策中再做另一个决策。嵌套 if 语句 (nested if statements) 是把一个条件语句放在另一个条件语句中,这样你就能在初始条件满足之后再检查额外条件。

8.4.1) 理解嵌套条件语句

嵌套 if 语句很强大,因为它们让你避免检查那些尚不合理的条件。例如,如果用户没有账户,就没有必要询问密码。嵌套可以让你按真实世界的决策过程来组织逻辑:有些问题只有在其他问题先得到回答后才有意义。

一个嵌套的 if 语句,简单来说就是在另一个 if 块内部放一个 if 语句(或 if-elif-else 链):

python
if outer_condition:
    # 当 outer_condition 为 True 时执行这段代码
    if inner_condition:
        # 当两个条件都为 True 时执行这段代码
        inner_block
    else:
        # 当 outer_condition 为 True 但 inner_condition 为 False 时执行
        inner_else_block
else:
    # 当 outer_condition 为 False 时执行
    outer_else_block

只有当外层条件为 True 时,内层 if 语句才会被计算。这会创建一个决策的层级结构。

开始

外层条件为 True?

执行外层 else 块

内层条件为 True?

执行内层 if 块

执行内层 else 块

继续

结束

下面是一个简单示例:

python
# account_login.py
has_account = input("Do you have an account? (yes/no): ").lower() == "yes"
 
if has_account:
    print("Welcome back!")
    password = input("Enter your password: ")
    
    if password == "secret123":
        print("Login successful!")
        print("Access granted to your dashboard.")
    else:
        print("Incorrect password.")
        print("Access denied.")
else:
    print("Please create an account first.")
    print("Visit our registration page.")

如果你回答 "yes" 并输入正确密码:

Welcome back!
Login successful!
Access granted to your dashboard.

如果你回答 "yes" 但输入错误密码:

Welcome back!
Incorrect password.
Access denied.

如果你回答 "no":

Please create an account first.
Visit our registration page.

注意密码检查只有在用户有账户时才会发生。这就是嵌套的关键好处——你可以避免不必要的检查。

8.4.2) 何时使用嵌套 if 语句

嵌套 if 语句在以下情况很有用:

  1. 决策依赖前一个决策:只有在满足某个条件后才需要检查另一个内容
  2. 创建决策树:每一层都会缩小可能性
  3. 验证前置条件:在检查更细节的要求之前先检查基本要求
  4. 避免不必要的检查:当早期条件失败时跳过开销较大的操作

示例:贷款资格

python
# loan_eligibility.py
age = int(input("Enter your age: "))
 
if age >= 18:
    print("Age requirement met.")
    income = float(input("Enter your annual income: $"))
    
    if income >= 30000:
        print("Income requirement met.")
        credit_score = int(input("Enter your credit score: "))
        
        if credit_score >= 650:
            print("Congratulations! You are eligible for a loan.")
            print("Please proceed to the application form.")
        else:
            print("Sorry, your credit score is too low.")
            print("Minimum required: 650")
    else:
        print("Sorry, your income is too low.")
        print("Minimum required: $30,000")
else:
    print("Sorry, you must be 18 or older to apply.")

这会创建一个决策树,其中每一层都依赖于前一层。如果年龄小于 18,我们就不会再询问收入或信用评分。

8.4.3) 避免过度嵌套

虽然嵌套很强大,但层级过多会让代码难以阅读和理解。考虑下面这个深度嵌套的示例:

python
# 嵌套太深 - 很难看懂
if condition1:
    if condition2:
        if condition3:
            if condition4:
                if condition5:
                    print("All conditions met!")

这很难阅读和维护。以下是减少嵌套的策略:

策略 1:在合适时合并条件

我们会在第 9 章详细学习 and 运算符,但现在只需要知道它可以让你一次检查多个条件:

python
# 更好:使用 'and' 合并条件(第 9 章会完整解释)
# 我们将在第 9 章学习 'and',但现在只要知道它会检查
# 所有条件是否都为真
if condition1 and condition2 and condition3 and condition4 and condition5:
    print("All conditions met!")

策略 2:使用提前返回(在使用函数时,我们会在第 19 章学习):

python
# 在函数中,我们可以提前 return
def check_eligibility(age, income, credit_score):
    if age < 18:
        return "Too young"
    if income < 30000:
        return "Income too low"
    if credit_score < 650:
        return "Credit score too low"
    return "Eligible"

策略 3:在合适时用 elif 展平:

python
# 不用嵌套 if 来检查范围,而是用 elif
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
# ... 依此类推

8.5) 常见的 if 语句陷阱(缩进、冒号与逻辑)

即使是有经验的程序员也会在 if 语句上犯错。本节涵盖初学者最常遇到的错误以及如何避免它们。

8.5.1) 缩进错误

Python 使用缩进来确定哪些语句属于哪个代码块。错误的缩进是最常见的错误来源之一。

问题 1:缺少缩进

python
# 错误 - IndentationError
age = 20
 
if age >= 18:
print("You are an adult.")  # 没有缩进!

这会产生:

  File "example.py", line 4
    print("You are an adult.")
    ^
IndentationError: expected an indented block

解决方案:始终缩进 if 语句下方的代码块:

python
# 正确
age = 20
 
if age >= 18:
    print("You are an adult.")  # 缩进正确

问题 2:缩进不一致

python
# 错误 - 混用空格与制表符,或空格数量不一致
if temperature > 30:
    print("It's hot!")
      print("Stay hydrated!")  # 多了空格 - 缩进不一致

解决方案:使用一致的缩进(4 个空格是 Python 的标准):

python
# 正确
if temperature > 30:
    print("It's hot!")
    print("Stay hydrated!")  # 相同的缩进层级

问题 3:嵌套层级缩进错误

python
# 错误 - 缩进层级不正确
if has_account:
    print("Welcome!")
    if password == "correct":
    print("Login successful!")  # 应该再多缩进一层

解决方案:每增加一层嵌套都需要额外缩进:

python
# 正确
if has_account:
    print("Welcome!")
    if password == "correct":
        print("Login successful!")  # 嵌套块缩进正确

8.5.2) 缺少冒号

ifelifelse 行末尾的冒号 (:) 是必需的。忘记它是非常常见的错误:

python
# 错误 - SyntaxError: missing colon
if age >= 18
    print("Adult")

这会产生:

  File "example.py", line 2
    if age >= 18
                ^
SyntaxError: invalid syntax

解决方案:始终包含冒号:

python
# 正确
if age >= 18:
    print("Adult")

elifelse 也是一样:

python
# 正确 - 所有冒号都存在
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
else:
    grade = "F"

8.5.3) 错误的比较运算符

问题 1:使用赋值 (=) 代替比较 (==)

python
# 错误 - 这会把 18 赋值给 age,而不是比较!
age = 20
 
if age = 18:  # SyntaxError
    print("You are 18")

解决方案:使用 == 进行比较:

python
# 正确
age = 20
 
if age == 18:
    print("You are 18")

8.5.4) 由于逻辑错误导致代码不可达

问题:永远不可能为 True 的条件

python
# 错误 - elif 永远不会执行
score = 85
 
if score >= 60:
    print("You passed!")
elif score >= 80:  # This will never execute!
    print("You got a B!")

如果 score 是 85,第一个条件(score >= 60)为 True,因此 elif 永远不会被检查。顺序是错的。

解决方案:将条件从最具体到最不具体排序:

python
# 正确
score = 85
 
if score >= 80:
    print("You got a B!")
elif score >= 60:
    print("You passed!")

8.5.5) 空的 if 代码块

在 Python 中,你不能有一个空的 if 代码块:

python
# 错误 - SyntaxError
if temperature > 30:
    # 我稍后会在这里添加代码
 
print("Done")

这会产生:

  File "example.py", line 3
    print("Done")
    ^
IndentationError: expected an indented block

解决方案:使用 pass 语句作为占位符(下一节会介绍):

python
# 正确 - 使用 pass 作为占位符
if temperature > 30:
    pass  # TODO: 我稍后会在这里添加代码
 
print("Done")

8.6) 在代码块中使用 pass 作为占位符

有时在写代码时,你知道需要一个 if 语句,但还没决定要在里面写什么。Python 不允许空代码块,所以你需要一种方式来创建一个有效但“什么也不做”的代码块。这就是 pass 语句 (pass statement) 的用途。

8.6.1) pass 是什么?

pass 语句是一个 空操作 (null operation)——当 Python 执行它时,什么都不会发生。它是一个占位符,让你即使还没准备好实现,也能写出语法正确的代码。

python
if condition:
    pass  # 暂时什么也不做

pass 理解为告诉 Python:“我知道这里需要代码,但我以后再补上。”它在开发过程中尤其有用,当你在勾勒程序结构时。

8.6.2) 为什么需要 pass

Python 要求每个代码块中至少有一条语句。空代码块会导致语法错误:

python
# 错误 - 这会导致错误
if age >= 18:
    # TODO: 在这里添加成人逻辑
 
print("Done")

Error:

  File "example.py", line 3
    print("Done")
    ^
IndentationError: expected an indented block

使用 pass 可以让代码在语法上有效:

python
# 正确 - 使用 pass 作为占位符
if age >= 18:
    pass  # TODO: 在这里添加成人逻辑
 
print("Done")

8.6.3) pass 的常见用途

用途 1:开发过程中的占位符

当你在规划程序结构但还没实现全部内容时:

python
# user_system.py
user_type = input("Enter user type (admin/user/guest): ").lower()
 
if user_type == "admin":
    pass  # TODO: 实现 admin 功能
elif user_type == "user":
    pass  # TODO: 实现 user 功能
elif user_type == "guest":
    print("Welcome, guest! Limited access granted.")
else:
    print("Invalid user type.")

这让你可以运行程序并测试已实现的部分,同时为未来工作保留占位符。

用途 2:在某个分支中有意什么也不做

有时你确实想在某些情况下什么都不做,但又需要处理其他情况:

python
# positive_numbers.py
# 只处理正数
number = int(input("Enter a number: "))
 
if number > 0:
    result = number * 2
    print(f"Double of {number} is {result}")
elif number == 0:
    pass  # 0 是有效值,但不需要任何操作
else:
    print("Negative numbers are not allowed.")

8.6.4) 其他场景中的 pass

虽然我们聚焦在 if 语句中的 pass,但随着你学习更多 Python,你也会在其他场景中遇到它:

  • 函数 (functions)(第 20 章):用作函数体的占位符
  • 类 (classes)(第 31 章):用作类定义的占位符
  • 循环 (loops)(第 11-12 章):用作循环体的占位符
  • 异常处理器 (exception handlers)(第 29 章):有意忽略错误

现在请记住,当你需要创建一个有效但空的代码块时,pass 就是你的工具。


统整回顾

在本章中,你学习了如何使用条件语句让程序变得更智能、更具响应性。我们来回顾关键概念:

简单 if 语句 只在条件为真时执行代码:

python
if temperature > 30:
    print("It's hot outside!")

if-else 语句 在两个备选项之间选择:

python
if age >= 18:
    print("Adult")
else:
    print("Minor")

if-elif-else 处理多个互斥的选项:

python
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
else:
    grade = "F"

嵌套 if 语句 在决策中再做决策:

python
if has_account:
    if password_correct:
        print("Welcome!")
    else:
        print("Wrong password")
else:
    print("Create an account")

需要避免的常见陷阱

  • ifelifelse 后缺少冒号
  • 缩进错误或缩进不一致
  • = 代替 == 进行比较
  • elif 链中顺序错误
  • 没有 pass 的空代码块

pass 语句 可在开发过程中为“空代码块”提供占位符。

你现在已经拥有了根据条件编写智能决策程序的工具。在下一章,我们将学习 布尔逻辑运算符 (boolean logic operators)andornot),它们能让你组合多个条件,从而实现更复杂的决策逻辑。这会让你的 if 语句更强大、更具表达力。

© 2025. Primesoft Co., Ltd.
support@primesoft.ai