Python 赋值运算符实战:写出稳健、清晰的变量赋值

2026-08-06 41 预计阅读时间: 1 分钟
来源: realpython.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:7 分钟

在 Python 中,赋值运算符不只是把一个值放进变量。它还承担着变量初始化、状态更新、批量绑定,以及在表达式中保存中间结果等任务。掌握这些写法,可以让代码更短,但更重要的是让状态变化更容易阅读和维护。

从初始化开始:让变量有明确的起点

最基本的赋值使用单个等号:

user_name = "Lin"
login_count = 0
is_active = True

等号的作用是把右侧表达式计算出的结果绑定到左侧名称。右侧可以是字面量、函数调用,也可以是更复杂的表达式:

price = 19.9
quantity = 3
total = price * quantity

print(f"{user_name}: {total:.2f}")

建议在变量第一次使用前完成初始化,尤其是在条件分支中。下面的写法可能在 has_discountFalse 时使用一个尚未定义的变量:

# 不够稳健
if has_discount:
    final_price = price * 0.9

print(final_price)

可以先给变量一个默认值,再根据条件更新它:

final_price = price

if has_discount:
    final_price *= 0.9

print(final_price)

这种写法把变量的生命周期表达得更清楚,也避免了 UnboundLocalErrorNameError

批量赋值与解包:减少重复代码

Python 支持同时给多个变量赋值:

width, height = 1920, 1080

也可以利用解包交换两个变量,而不需要临时变量:

width, height = height, width

解包要求左右两侧的结构匹配。处理长度可能变化的数据时,可以使用星号收集剩余元素:

first, *middle, last = [10, 20, 30, 40, 50]

print(first)   # 10
print(middle)  # [20, 30, 40]
print(last)    # 50

如果数据格式不稳定,直接解包可能抛出 ValueError。这时应先校验长度,或者使用更明确的索引和默认值逻辑,而不是为了追求简短而隐藏输入约束。

用增强赋值表达状态更新

增强赋值把运算和重新赋值合并在一起:

score = 10
score += 5
score *= 2
score -= 3

print(score)  # 27

常见形式包括:

count += 1
balance -= payment
ratio *= factor
average /= sample_count
remainder %= divisor

它们适合表达“基于当前值更新状态”。对于列表,+= 还会体现出可变对象的行为差异:

items = ["book"]
alias = items
items += ["pen"]

print(items)  # ['book', 'pen']
print(alias)  # ['book', 'pen']

这里列表对象被原地扩展,alias 仍然指向同一个列表。相比之下,使用普通赋值可能创建新的列表对象:

items = ["book"]
alias = items
items = items + ["pen"]

print(items)  # ['book', 'pen']
print(alias)  # ['book']

因此,处理列表、字典等可变对象时,要明确自己需要的是原地修改还是创建新对象。

海象运算符:在条件中保存结果

海象运算符 := 可以在表达式中完成赋值。它适合“计算一次,同时判断或继续使用结果”的场景:

message = "Python makes assignment expressive"

if (length := len(message)) > 20:
    print(f"消息长度为 {length},超过 20 个字符")

读取输入时,海象运算符可以避免重复调用:

# 运行后输入一行文本;输入空行结束
while (line := input("请输入内容:").strip()):
    print(f"收到:{line}")

不过,海象运算符会增加表达式密度。若赋值和判断组合后难以一眼读懂,普通的两步写法通常更好:

line = input("请输入内容:").strip()
if line:
    print(f"收到:{line}")

它尤其适合循环条件、正则匹配结果或昂贵计算结果需要立即复用的地方,不应为了少写一行代码而到处使用。

一个可运行的小例子

下面的程序演示了初始化、增强赋值、解包和海象运算符。保存为 assignment_demo.py 后即可运行:

from typing import Iterable


def summarize_scores(scores: Iterable[int]) -> tuple[int, float]:
    total = 0
    count = 0

    for score in scores:
        total += score
        count += 1

    average = total / count if count else 0.0
    return total, average


passed, failed = 3, 1
passed += 2
failed += 1

total, average = summarize_scores([88, 92, 76, 100])

if (rounded_average := round(average, 1)) >= 90:
    result = "优秀"
else:
    result = "继续提升"

print(f"通过:{passed},未通过:{failed}")
print(f"总分:{total},平均分:{rounded_average},评价:{result}")

这个例子中,passed += 2failed += 1 清楚地表示计数器更新;total, average = ... 使用解包接收函数返回值;rounded_average := ... 在判断时保存已经计算好的结果。

写稳健赋值时的检查清单

  • 变量第一次使用前是否已经初始化?
  • 条件分支是否覆盖了变量的所有使用路径?
  • 多变量解包的输入长度是否可靠?
  • += 用在可变对象上时,是否确实需要原地修改?
  • 海象运算符是否让代码更容易阅读,而不是更难?
  • 变量名是否表达了值的含义和单位,例如 timeout_seconds 而不是含义模糊的 timeout

好的赋值代码不在于使用最多的语法,而在于清楚表达数据从哪里来、如何初始化,以及何时发生变化。对简单状态使用普通赋值,对累计和更新使用增强赋值,对结构化返回值使用解包;只有在能减少重复计算且不损害可读性时,才引入海象运算符。


相关推荐