Python 3.5中算术、逻辑与位运算符代码示例
深入解析Python 3.5中的算术运算符(含新增矩阵乘法@)、逻辑运算符(短路求值原理)与位运算符(二进制补码机制),配备完整可执行代码示例与高清图解。
@)。本文将全面梳理这三类运算符的语法、运行机制与实际代码示例,重点剖析短路求值逻辑、二进制补码运算规则及版本专属特性,帮助开发者写出准确、高效的Python代码。
一、Python 3.5 运算符分类与体系全貌
运算符是让程序执行特定数学或逻辑计算的专用符号或关键字。在Python 3.5中,运算符主要划分为算术运算符、逻辑运算符与位运算符三大核心类别。理解它们各自的运算规则、操作数类型以及返回值类型,是构建健壮程序逻辑的前提。
二、算术运算符详解与 Python 3.5 矩阵乘法 (@)
Python 3.5包含基础的四则混合运算、整除、取模、幂运算,以及该版本正式引入的矩阵乘法专用运算符。与Python 2存在显著区别的是,Python 3中两个整数相除采用“真除法”(/),其运算结果始终是浮点数(float)。
1. 常用算术运算符语法与行为
- 加法(
+)与减法(-):执行代数相加或相减,也支持重载用于字符串、列表等序列的拼接。 - 乘法(
*)与幂运算(**):a ** b表示 a 的 b 次幂,右结合性。 - 真除法(
/):即使能被整除,结果也强制转换为浮点类型,例如4 / 2得到2.0。 - 向下取整除法(
//):向负无穷方向取整(Floor Division)。例如7 // 2得到3,而-7 // 2得到-4。 - 求模/余数(
%):遵循恒等式a = (a // b) * b + (a % b)。余数的符号始终与除数b保持一致。
# 算术运算符综合示例
a = 14
b = 4
print("加法 a + b =", a + b)
print("减法 a - b =", a - b)
print("乘法 a * b =", a * b)
print("真除法 a / b =", a / b) # 注意:返回 float
print("整除 a // b =", a // b) # 向负无穷截断
print("取模 a % b =", a % b)
print("幂运算 a ** 2 =", a ** 2)
# 负数运算的向下取整与取模
print("-14 // 4 =", -14 // 4) # 结果为 -4 (而非 -3)
print("-14 % 4 =", -14 % 4) # (-4 * 4) + 2 = -14,余数为 2
print("14 % -4 =", 14 % -4) # (-4 * -4) + (-2) = 14,余数为 -2
减法 a - b = 10
乘法 a * b = 56
真除法 a / b = 3.5
整除 a // b = 3
取模 a % b = 2
幂运算 a ** 2 = 196
-14 // 4 = -4
-14 % 4 = 2
14 % -4 = -2
2. Python 3.5 核心新特性:矩阵乘法运算符(@)
在Python 3.5之前,科学计算库(如NumPy)只能使用 numpy.dot(A, B) 或 A.dot(B) 实现矩阵相乘,因为通用的 * 运算符已经被定义为对应元素的逐项相乘(Hadamard积)。这导致复杂的代数公式表达冗长且难以阅读。
PEP 465在Python 3.5中正式引入中缀运算符 @ 及其对应的魔术方法 __matmul__、__rmatmul__ 和 __imatmul__。内置类型本身未默认实现该方法,但允许类库和自定义类直接重载。
# 自定义实现支持 @ 矩阵乘法的简易矩阵类
class SimpleMatrix:
def __init__(self, data):
self.data = data
self.rows = len(data)
self.cols = len(data[0])
def __matmul__(self, other):
# 实现 PEP 465 规定的 @ 运算符
if self.cols != other.rows:
raise ValueError("矩阵维度不匹配:无法进行点乘")
# 初始化结果矩阵尺寸: self.rows x other.cols
result = [[0] * other.cols for _ in range(self.rows)]
for i in range(self.rows):
for j in range(other.cols):
for k in range(self.cols):
result[i][j] += self.data[i][k] * other.data[k][j]
return SimpleMatrix(result)
def __repr__(self):
return "SimpleMatrix({})".format(self.data)
# 实例化两个 2x2 矩阵
m1 = SimpleMatrix([[1, 2], [3, 4]])
m2 = SimpleMatrix([[5, 6], [7, 8]])
# 在 Python 3.5+ 中直接使用 @ 进行矩阵乘法
m3 = m1 @ m2
print("m1 @ m2 运算结果:", m3)
三、逻辑运算符与短路求值(Short-circuit Evaluation)
Python中的逻辑运算符只有三个关键字:and、or、not。与其他语言常返回严格的布尔值 true/false 不同,Python中 and 与 or 采用短路求值原则,并直接返回最后一个被求值表达式的真实对象。
1. 真值测试规则(Truth Value Testing)
任何Python对象都可在逻辑判断中使用。以下对象在布尔上下文中被视为“假”(False):
- 常量:
None、False - 数值零值:
0、0.0、0j、Decimal(0) - 空序列与集合:
''(空字符串)、()(空元组)、[](空列表)、{}(空字典)、set()
除上述情况外的所有其他对象均被视为“真”(True)。
2. 短路逻辑代码示例与安全性应用
短路机制最常见的实战价值在于条件守卫(Guard Clause):在执行可能引发异常或耗时较长的后置函数前,先通过前置表达式拦截无效状态。例如在访问对象属性前判断是否非空,或在做除法前检查分母是否为零。
# 1. 基础返回值验证:返回操作数本身而非布尔值
res1 = 0 and "Python"
res2 = 100 and "Python"
print("0 and 'Python' ->", repr(res1))
print("100 and 'Python' ->", repr(res2))
res3 = "默认名称" or "备用名称"
res4 = "" or "备用名称"
print("'默认名称' or '备用名称' ->", repr(res3))
print("'' or '备用名称' ->", repr(res4))
# 2. not 运算始终返回布尔类型
print("not '' ->", not '')
print("not [1, 2] ->", not [1, 2])
# 3. 短路求值防崩溃实战:避免 ZeroDivisionError 与 NoneAttribute 访问
denominator = 0
# 如果没有短路,denominator != 0 之后的 (10 / denominator) 会直接抛出 ZeroDivisionError
is_valid = (denominator != 0) and (10 / denominator > 1)
print("零分母守卫运算结果:", is_valid)
# 4. 函数调用触发验证
def trigger():
print(">>> 警告: 右侧表达式 trigger() 被执行了!")
return True
print("测试 False and trigger():")
result_a = False and trigger() # trigger 不会执行
print("测试 True or trigger():")
result_b = True or trigger() # trigger 不会执行
100 and 'Python' -> 'Python'
'默认名称' or '备用名称' -> '默认名称'
'' or '备用名称' -> '备用名称'
not '' -> True
not [1, 2] -> False
零分母守卫运算结果: False
测试 False and trigger():
测试 True or trigger():
四、位运算符与二进制补码机制
位运算符直接作用于整数的底层二进制位(Bits)。Python 3.5中的整数拥有任意精度(即理论上不溢出),但在位运算的行为模式上,依然严格遵循二进制补码(Two's Complement)模型,符号位向高位无限扩展。
1. 六大位运算符定义
- 按位与(
&):两个操作数对应二进制位都为1时,该位结果才为1;常用于掩码(Mask)提取特定位。 - 按位或(
|):两个操作数对应位只要有一个为1,该位结果即为1;常用于状态标志置位(Set Flags)。 - 按位异或(
^):对应位数值相异(一个为0一个为1)时结果为1,相同为0;常用于无辅助变量值交换或状态翻转。 - 按位取反(
~):单目运算符,对二进制位每一位取反(0变1,1变0)。根据补码规则,恒有~x = -(x + 1)。 - 左移位(
<<):二进制位整体向左移动指定位数,低位补0。在不溢出范围内,每左移1位等价于乘以2。 - 右移位(
>>):二进制位整体向右移动,舍弃低位。Python采用算术右移,高位补充符号位(正数补0,负数补1)。每右移1位等价于向下整除2。
# 定义两个整型操作数
x = 10 # 二进制: 0b1010
y = 12 # 二进制: 0b1100
print("x = {:2d} (0b{:08b})".format(x, x))
print("y = {:2d} (0b{:08b})".format(y, y))
print("-" * 35)
# 1. 逻辑位运算
bit_and = x & y # 0b1000 -> 8
bit_or = x | y # 0b1110 -> 14
bit_xor = x ^ y # 0b0110 -> 6
print("x & y = {:2d} (0b{:08b})".format(bit_and, bit_and))
print("x | y = {:2d} (0b{:08b})".format(bit_or, bit_or))
print("x ^ y = {:2d} (0b{:08b})".format(bit_xor, bit_xor))
# 2. 按位取反
bit_not = ~x # -(10 + 1) = -11
print("~x = {:2d} (数学公式: -(x + 1) = {})".format(bit_not, -(x + 1)))
# 3. 移位运算
shift_left = x << 2 # 10 * 4 = 40 (0b00101000)
shift_right = x >> 1 # 10 // 2 = 5 (0b00000101)
print("x << 2 = {:2d} (0b{:08b})".format(shift_left, shift_left))
print("x >> 1 = {:2d} (0b{:08b})".format(shift_right, shift_right))
# 4. 负数右移测试(算术右移验证)
neg = -14
print("-14 >> 1 = {} (等价于 -14 // 2)".format(neg >> 1))
y = 12 (0b00001100)
-----------------------------------
x & y = 8 (0b00001000)
x | y = 14 (0b00001110)
x ^ y = 6 (0b00000110)
~x = -11 (数学公式: -(x + 1) = -11)
x << 2 = 40 (0b00101000)
x >> 1 = 5 (0b00000101)
-14 >> 1 = -7 (等价于 -14 // 2)
五、运算符优先级与组合避坑指南
当多个算术、位运算和逻辑运算符出现在同一行表达式中时,解释器将严格依照预设的优先级与结合性进行解析。不恰当的联合编写容易引发反直觉的隐蔽Bug。
在C、C++及Python中,比较运算符(如 ==, !=, <, >)的优先级均高于按位与(&)、按位或(|)和按位异或(^)。
例如判断变量 flags 的最低位是否为1:若编写为 if flags & 1 == 1:,解释器实际会先计算 1 == 1(得到 True 即 1),再计算 flags & 1;而如果写成 if flags & 2 == 2:,则先计算 2 == 2 得到 1,最终变为 flags & 1,导致完全错误的逻辑判断!
# 陷阱 1:按位与 & 与比较 == 的优先级问题
state = 0b0010 # 十进制 2
# 错误写法:== 优先于 &
# 实际被解释为: state & (2 == 2) -> state & 1 -> 2 & 1 -> 0 -> False
if state & 2 == 2:
print("错误写法判定为 True")
else:
print("错误写法判定为 False (Bug发生!)")
# 正确写法:显式添加圆括号
if (state & 2) == 2:
print("正确写法: 成功匹配状态位 2")
# 陷阱 2:连续幂运算的右结合特性
# 2 ** 3 ** 2 等价于 2 ** (3 ** 2) = 2 ** 9 = 512
# 而非 (2 ** 3) ** 2 = 8 ** 2 = 64
calc = 2 ** 3 ** 2
print("2 ** 3 ** 2 实际计算结果:", calc)
# 陷阱 3:加减法优先于位移
# 1 + 2 << 1 实际计算为 (1 + 2) << 1 = 3 << 1 = 6
# 而非 1 + (2 << 1) = 1 + 4 = 5
shift_calc = 1 + 2 << 1
print("1 + 2 << 1 实际计算结果:", shift_calc)
正确写法: 成功匹配状态位 2
2 ** 3 ** 2 实际计算结果: 512
1 + 2 << 1 实际计算结果: 6
六、总结与速查清单
通过本文的分解讲解与代码演示,我们可以归纳出Python 3.5在运算符使用上的关键原则:
- 算术运算遵循强类型精度:整数真除法
/必然产生浮点数;整除//始终向下朝着负无穷截断;Python 3.5正式提供的@运算符为多维数据提供了优雅的矩阵点乘标准接口。 - 逻辑运算立足短路特性:
and和or不仅仅是逻辑判定工具,更常作为返回首个命中对象的安全守卫与默认赋值手段。 - 位运算紧扣补码法则:整型位运算提供无限长度支持,按位取反满足
~x == -(x + 1),移位操作符号位自动延展。 - 复杂表达式坚持括号显式化:针对位运算符与比较运算符混用的场景,主动添加小括号是杜绝隐蔽优先级错误的最稳妥手段。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













