飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 Python简介

    • Python是什么
    • 安装与运行
    • 交互式解释器
    • 注释与编码规范
  • 第2章 变量与数据类型

    • 变量与对象
    • 整数 int
    • 浮点数 float
    • 复数 complex
    • 布尔值 bool
    • 字符串 str
    • 空值 None
    • 类型转换
  • 第3章 运算符与表达式

    • 算术运算符
    • 比较运算符
    • 赋值运算符
    • 逻辑运算符
    • 位运算符
    • 身份与成员运算符
    • 海象运算符
    • 运算符优先级
  • 第4章 流程控制

    • if 语句
    • if-else 语句
    • if-elif-else 语句
    • match-case 语句
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 函数
    • break 与 continue
    • 循环的 else 子句
    • pass 语句
  • 第5章 数据结构

    • 列表创建与索引
    • 列表方法
    • 列表推导式
    • 元组
    • 序列解包
    • 集合
    • 字典创建与访问
    • 字典方法
    • 字典推导式
    • range 对象
  • 第6章 函数

    • 定义函数
    • 位置参数与关键字参数
    • 默认参数
    • 可变参数
    • 解包实参
    • 函数返回值
    • lambda 表达式
    • 文档字符串与注解
    • 作用域与命名空间
    • global 与 nonlocal
  • 第7章 模块与包

    • 模块导入
    • 模块搜索路径
    • 包与相对导入
    • 标准库概览
  • 第8章 文件与输入输出

    • 文件读写
    • 上下文管理器
    • 字符串格式化
    • JSON 与 CSV
  • 第9章 面向对象

    • 类与对象
    • 方法
    • 实例变量与类变量
    • 私有变量
    • 继承
    • 多重继承
    • 魔术方法
    • 属性装饰器
    • 数据类 dataclass
  • 第10章 异常处理

    • 语法错误与异常
    • try-except
    • 异常链与 raise
    • 清理操作
    • 自定义异常
  • 第11章 迭代器与生成器

    • 迭代器协议
    • 生成器
    • 生成器表达式
    • 迭代工具
  • 第12章 高级特性

    • 装饰器
    • 函数式编程
  • 第13章 工程实践

    • 测试与调试
    • 代码质量
    • 虚拟环境

赋值运算符

赋值运算符是 Python 中将对象绑定到名字的核心机制。= 是最基础的赋值形式,而 +=、-=、*=、/=、//=、%=、**= 等复合赋值运算符则在修改变量时提供了更简洁的语法。此外,Python 的多重赋值和序列解包让一次为多个变量赋值成为可能。

基础赋值 =

= 将右侧表达式的结果绑定到左侧的名字。Python 的赋值不是"把值存入变量",而是"让名字引用对象"。

>>> width = 20
>>> height = 5 * 9
>>> width * height
900

如果变量未定义就使用,会触发 NameError:

>>> n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

多重赋值

Python 允许用一条语句为多个变量赋值。右侧表达式从左到右依次求值,然后同时绑定到左侧变量。这意味着可以在不使用临时变量的情况下交换两个值。

>>> a, b = 0, 1
>>> a
0
>>> b
1

# 交换变量
>>> a, b = b, a
>>> a
1
>>> b
0

多重赋值的右侧在赋值发生前完全求值,因此 a, b = b, a + b 这类表达式能正确工作:右侧的 a + b 使用的是赋值前的旧值。

>>> a, b = 0, 1
>>> a, b = b, a + b
>>> a, b
(1, 1)      # a 获得旧 b(1),b 获得旧 a+旧 b(0+1)

这种特性在实现斐波那契数列时特别优雅:

>>> a, b = 0, 1
>>> while a < 10:
...     print(a)
...     a, b = b, a + b
...
0
1
1
2
3
5
8

链式赋值

链式赋值 a = b = c = 0 将同一个对象同时绑定到多个名字。注意这并不意味着创建多个独立副本——如果绑定的是可变对象,通过任一名字修改都会影响其他名字。

>>> a = b = []
>>> a.append(1)
>>> b
[1]         # a 和 b 引用同一个列表

>>> x = y = 5
>>> x += 1
>>> x
6
>>> y
5           # 整数不可变,x 现在引用新对象 6,y 仍引用 5

复合赋值运算符

复合赋值运算符将运算和赋值合并,形式为 变量 运算符= 表达式,等价于 变量 = 变量 运算符 表达式。但两者并非完全等价,复合赋值对可变对象可能执行就地修改。

>>> salary = 10000
>>> salary += 2000      # 等价于 salary = salary + 2000
>>> salary
12000

>>> count = 100
>>> count //= 3         # count = count // 3
>>> count
33

>>> base = 2
>>> base **= 10         # base = base ** 10
>>> base
1024

对于不可变类型(数字、字符串、元组),a += b 与 a = a + b 效果相同,都是创建新对象。对于可变类型如列表,+= 调用 __iadd__ 方法执行就地扩展,比 a = a + b 更高效:

>>> a = [1, 2]
>>> id_before = id(a)
>>> a += [3, 4]         # 就地扩展,a 的 id 不变
>>> id(a) == id_before
True

>>> b = [1, 2]
>>> id_before = id(b)
>>> b = b + [3, 4]      # 创建新列表,b 的 id 改变
>>> id(b) == id_before
False

所有算术复合赋值运算符一览:

>>> x = 10
>>> x += 5;   print(x)   # 15
>>> x -= 3;   print(x)   # 12
>>> x *= 2;   print(x)   # 24
>>> x /= 4;   print(x)   # 6.0
>>> x //= 2;  print(x)   # 3.0
>>> x %= 2;   print(x)   # 1.0
>>> x **= 3;  print(x)   # 1.0

序列解包赋值

Python 支持将可迭代对象解包到多个变量。左侧的变量数量必须与右侧可迭代对象的元素数量匹配,否则会触发 ValueError。

>>> coordinates = (3, 4)
>>> x, y = coordinates
>>> x
3
>>> y
4

>>> data = [1, 2, 3]
>>> first, second, third = data
>>> first
1

解包不限于元组和列表,任何可迭代对象都可以:

>>> a, b, c = "xyz"
>>> a
'x'

>>> head, tail = [1, 2, 3, 4, 5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

扩展解包(星号表达式)

Python 3 引入了星号表达式 *rest,可以捕获任意数量的剩余元素。一个解包表达式中只能有一个星号变量。

>>> first, *rest = [1, 2, 3, 4, 5]
>>> first
1
>>> rest
[2, 3, 4, 5]

>>> *beginning, last = [1, 2, 3, 4, 5]
>>> beginning
[1, 2, 3, 4]
>>> last
5

>>> first, *middle, last = [1, 2, 3, 4, 5]
>>> first, middle, last
(1, [2, 3, 4], 5)

星号变量总是得到列表,即使原始序列是元组或字符串:

>>> a, *b = (1, 2, 3)
>>> b
[2, 3]      # 列表,不是元组

如果只给星号变量赋值,它会捕获所有元素:

>>> *all_items, = (1, 2, 3)
>>> all_items
[1, 2, 3]   # 将元组转为列表的技巧

嵌套解包

解包可以嵌套,用于处理嵌套序列:

>>> data = ('Alice', (25, 'Engineer'))
>>> name, (age, job) = data
>>> name
'Alice'
>>> age
25
>>> job
'Engineer'

解包的应用场景

解包赋值让代码更简洁。遍历字典时,可以直接解包键值对:

>>> scores = {'Alice': 85, 'Bob': 92}
>>> for name, score in scores.items():
...     print(f"{name}: {score}")
...
Alice: 85
Bob: 92

函数返回多个值时,调用方可以直接解包:

>>> def get_min_max(numbers):
...     return min(numbers), max(numbers)
...
>>> minimum, maximum = get_min_max([3, 1, 4, 1, 5])
>>> minimum
1
>>> maximum
5

赋值运算符看似简单,但复合赋值的就地修改特性、多重赋值的求值顺序、扩展解包的灵活语法,都是提高代码效率和可读性的关键工具。理解这些机制的内部行为,有助于避免可变对象共享引用带来的意外副作用。

上一页
比较运算符
下一页
逻辑运算符