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

    • 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 中可以用 bin() 函数查看整数的二进制形式,前缀 0b 表示二进制字面量。

>>> bin(5)
'0b101'
>>> bin(10)
'0b1010'
>>> 0b1010
10

位运算逐位操作两个整数的二进制位。为了直观展示,以下示例中所有数字都用 4 位二进制表示,实际 Python 整数精度不限。

按位与 &

两个对应位都为 1 时,结果位才为 1;否则为 0。& 常用于提取特定位(掩码操作)或判断权限。

>>> 5 & 3
1

# 二进制视角:
# 5 = 0b0101
# 3 = 0b0011
# &   0b0001 = 1

掩码操作是 & 的典型应用:通过与一个特定位模式的数进行与运算,可以保留感兴趣的位,清除其他位。

>>> flags = 0b1101       # 状态标志
>>> mask = 0b0100        # 只关心第 2 位
>>> flags & mask
4                        # 0b0100,第 2 位为 1
>>> bool(flags & mask)
True                     # 第 2 位被设置

按位或 |

两个对应位只要有一个为 1,结果位就为 1。| 常用于设置特定位或合并权限。

>>> 5 | 3
7

# 二进制视角:
# 5 = 0b0101
# 3 = 0b0011
# |   0b0111 = 7

设置标志位的常见模式:

>>> flags = 0b0000
>>> flags |= 0b0001      # 设置第 0 位
>>> flags |= 0b0100      # 设置第 2 位
>>> bin(flags)
'0b101'

按位异或 ^

两个对应位不同时结果为 1,相同时结果为 0。异或运算有一个重要性质:任何数与自身异或得 0,与 0 异或得自身。

>>> 5 ^ 3
6

# 二进制视角:
# 5 = 0b0101
# 3 = 0b0011
# ^   0b0110 = 6

异或的经典应用是交换两个数(无需临时变量)和简单加密:

>>> a = 5
>>> b = 3
>>> a = a ^ b            # a 现在是 5^3 = 6
>>> b = a ^ b            # b 现在是 6^3 = 5
>>> a = a ^ b            # a 现在是 6^5 = 3
>>> a, b
(3, 5)

按位取反 ~

~x 将整数的每一位取反,0 变 1,1 变 0。在 Python 中,整数使用补码表示且有无限精度,因此 ~x 等价于 -(x + 1)。

>>> ~5
-6
>>> ~0
-1
>>> ~(-1)
0

# 数学解释:~x == -x - 1
>>> ~100
-101

这个等价关系源于无限精度补码:所有位取反后再加 1 得到相反数,因此取反就是 -(x+1)。

左移 << 与右移 >>

x << n 将 x 的二进制位向左移动 n 位,右侧补 0,等效于 x * 2**n。x >> n 将位向右移动 n 位,左侧补符号位(正数补 0,负数补 1),等效于 x // 2**n。

>>> 5 << 2
20          # 5 * 4 = 20,0b0101 → 0b010100

>>> 20 >> 2
5           # 20 // 4 = 5,0b010100 → 0b0101

>>> 1 << 10
1024        # 2**10,快速计算 2 的幂

右移运算对负数执行算术右移(保留符号位):

>>> -20 >> 2
-5          # -20 // 4 = -5
>>> bin(-20 & 0xFF)      # 低 8 位视角
'0b11101100'

权限系统设计

位运算最常见的实际应用是权限系统。Linux 文件权限、数据库权限和 API 权限都广泛使用位掩码。

# 定义权限常量(每个权限占一位)
READ = 1 << 0      # 0b0001 = 1
WRITE = 1 << 1     # 0b0010 = 2
EXECUTE = 1 << 2   # 0b0100 = 4
ADMIN = 1 << 3     # 0b1000 = 8

# 授予权限(按位或)
user_perm = READ | WRITE        # 0b0011 = 3

# 检查权限(按位与)
>>> bool(user_perm & READ)
True
>>> bool(user_perm & EXECUTE)
False

# 添加权限
user_perm |= EXECUTE            # 现在拥有读、写、执行

# 移除权限(与掩码的反码进行与运算)
user_perm &= ~WRITE             # 移除写权限
>>> bool(user_perm & WRITE)
False

# 切换权限(异或)
user_perm ^= ADMIN              # 如果没有 ADMIN 则添加,有则移除

这种设计的优势在于:一个整数可以存储任意数量的布尔权限,检查、添加、移除操作都是 O(1) 的位运算。

负数位运算

Python 的整数有无限精度,负数使用补码的无限扩展形式。这导致负数的位运算结果可能与固定宽度语言(如 C 的 32 位 int)不同。

>>> bin(-5)
'-0b101'        # Python 的 bin() 显示带符号的简洁形式

# 与掩码配合查看补码表示
>>> bin(-5 & 0xFF)
'0b11111011'    # 8 位补码表示
>>> bin(-5 & 0xFFFFFFFF)
'0b11111111111111111111111111111011'   # 32 位补码

如果需要模拟固定宽度的位运算(如处理网络协议或硬件寄存器),通常通过与掩码进行与运算来截断:

def uint8(value):
    """将值限制为 8 位无符号整数"""
    return value & 0xFF

>>> uint8(-5)
251             # 0b11111011
>>> uint8(300)
44              # 300 & 0xFF = 44

位运算与集合运算的对应

位运算与集合运算存在直接对应关系,这在处理特征向量或标签集合时很有用:

# 集合视角
set_a = {0, 2}      # 0b0101 中为 1 的位
set_b = {0, 1}      # 0b0011 中为 1 的位

# 交集对应按位与
>>> 5 & 3
1                   # 只有位 0 在两个数中都为 1

# 并集对应按位或
>>> 5 | 3
7                   # 位 0、1、2 至少在一个数中为 1

# 对称差对应按位异或
>>> 5 ^ 3
6                   # 位 1 和 2 只在一个数中为 1

位运算符直接操作数据的底层表示,效率极高。权限系统设计展示了位运算的工程价值,而无限精度整数和补码机制则体现了 Python 在底层灵活性与高层抽象之间的平衡。处理固定宽度协议数据时,记得用掩码截断结果以匹配预期位宽。

上一页
逻辑运算符
下一页
身份与成员运算符