前言:运算符是程序的粘合剂

在前三篇文章中,我们学习了Python的基本语法、变量与数据类型。现在,我们将深入探讨将这些元素组合起来形成有意义的计算和逻辑判断的工具——运算符与表达式

运算符是程序中最基本的操作符号,它们像粘合剂一样将变量、常量和函数调用连接起来,形成表达式。表达式是程序中进行计算和逻辑判断的基本单位。深入理解运算符的特性、优先级和用法,是编写简洁、高效且正确代码的关键。

本文将全面解析Python中的各类运算符,通过丰富的实战案例,帮助你不仅理解每个运算符的用法,更能掌握它们在实际编程中的应用技巧和最佳实践。


一、 运算符概述与分类

在Python中,运算符是用于执行程序代码运算的特殊符号。根据功能,我们可以将运算符分为以下几类:

  1. 算术运算符:用于执行基本的数学运算
  2. 比较运算符:用于比较两个值
  3. 赋值运算符:用于给变量赋值
  4. 逻辑运算符:用于组合条件语句
  5. 位运算符:直接对整数进行位级操作
  6. 身份运算符:比较两个对象的内存地址
  7. 成员运算符:测试成员是否在序列中
  8. 海象运算符(Python 3.8+):在表达式内进行赋值

此外,我们还需要关注运算符的优先级和结合性,它们决定了表达式中运算的执行顺序。


二、 算术运算符:数学计算的基础

算术运算符用于执行基本的数学运算,如加、减、乘、除等。

2.1 基本算术运算符

实战案例4-1:基本算术运算

a = 10
b = 3

print(f"加法: {a} + {b} = {a + b}")        # 13
print(f"减法: {a} - {b} = {a - b}")        # 7
print(f"乘法: {a} * {b} = {a * b}")        # 30
print(f"除法: {a} / {b} = {a / b}")        # 3.333...
print(f"整除: {a} // {b} = {a // b}")      # 3
print(f"取模: {a} % {b} = {a % b}")        # 1
print(f"幂运算: {a} ** {b} = {a ** b}")    # 1000

# 浮点数运算
x = 10.5
y = 2.5
print(f"浮点数除法: {x} / {y} = {x / y}")  # 4.2
print(f"浮点数整除: {x} // {y} = {x // y}") # 4.0

# 复数运算
c1 = 2 + 3j
c2 = 1 - 2j
print(f"复数加法: {c1} + {c2} = {c1 + c2}")  # (3+1j)
print(f"复数乘法: {c1} * {c2} = {c1 * c2}")  # (8-1j)

2.2 算术运算符的优先级

算术运算符遵循数学中的优先级规则:幂运算 > 乘、除、取模、整除 > 加、减。

实战案例4-2:运算符优先级

result = 10 + 5 * 2 ** 3  # 2**3=8, 5*8=40, 10+40=50
print(f"10 + 5 * 2 ** 3 = {result}")  # 50

# 使用括号改变优先级
result = (10 + 5) * 2 ** 3  # 10+5=15, 2**3=8, 15*8=120
print(f"(10 + 5) * 2 ** 3 = {result}")  # 120

# 复杂的表达式
a, b, c = 2, 3, 4
result = a * b ** 2 + c // 2 - a % 3
# 计算步骤: b**2=9, a*9=18, c//2=2, a%3=2, 18+2-2=18
print(f"a * b ** 2 + c // 2 - a % 3 = {result}")  # 18

2.3 算术运算中的类型转换

当不同类型的数值进行运算时,Python会自动进行类型转换(类型提升)。

实战案例4-3:算术运算中的类型提升

# int 和 float 运算 → float
result = 5 + 3.14
print(f"5 + 3.14 = {result} (类型: {type(result)})")  # 8.14 <class 'float'>

# int 和 complex 运算 → complex
result = 5 + (2+3j)
print(f"5 + (2+3j) = {result} (类型: {type(result)})")  # (7+3j) <class 'complex'>

# float 和 complex 运算 → complex
result = 3.14 + (2+3j)
print(f"3.14 + (2+3j) = {result} (类型: {type(result)})")  # (5.14+3j) <class 'complex'>

# 布尔值参与运算 (True=1, False=0)
result = True + 5
print(f"True + 5 = {result} (类型: {type(result)})")  # 6 <class 'int'>

result = False * 3.14
print(f"False * 3.14 = {result} (类型: {type(result)})")  # 0.0 <class 'float'>

三、 比较运算符:关系判断的工具

比较运算符用于比较两个值,返回布尔值(True或False)。

3.1 基本比较运算符

实战案例4-4:比较运算符的应用

a = 10
b = 5
c = 10.0

print(f"等于: {a} == {c}{a == c}")        # True (值相等)
print(f"不等于: {a} != {b}{a != b}")      # True
print(f"大于: {a} > {b}{a > b}")          # True
print(f"小于: {a} < {b}{a < b}")          # False
print(f"大于等于: {a} >= {c}{a >= c}")    # True
print(f"小于等于: {b} <= {a}{b <= a}")    # True

# 字符串比较 (按字典序)
s1 = "apple"
s2 = "banana"
print(f"字符串比较: '{s1}' < '{s2}' → {s1 < s2}")  # True

# 链式比较
x = 5
print(f"链式比较: 1 < {x} <= 10 → {1 < x <= 10}")  # True
# 等价于: 1 < x and x <= 10

# 浮点数比较的注意事项
print(f"浮点数比较: 0.1 + 0.2 == 0.3 → {0.1 + 0.2 == 0.3}")  # False
# 应该使用容差比较
tolerance = 1e-10
result = abs((0.1 + 0.2) - 0.3) < tolerance
print(f"容差比较: |(0.1+0.2)-0.3| < {tolerance}{result}")  # True

3.2 比较运算符的链式使用

Python支持链式比较,可以使代码更加简洁易读。

实战案例4-5:链式比较的应用

# 判断一个数是否在某个范围内
x = 25
# 传统方式
if x >= 0 and x <= 100:
    print(f"{x} 在 0-100 范围内")
    
# 链式比较方式
if 0 <= x <= 100:
    print(f"{x} 在 0-100 范围内")

# 复杂的链式比较
a, b, c = 5, 10, 15
if a < b < c:
    print(f"{a} < {b} < {c}")

# 结合算术运算
x = 10
if 0 <= x * 2 <= 20:
    print(f"{x}*2 在 0-20 范围内")

# 实际应用:成绩等级判断
score = 85
if 90 <= score <= 100:
    grade = 'A'
elif 80 <= score < 90:
    grade = 'B'
elif 70 <= score < 80:
    grade = 'C'
elif 60 <= score < 70:
    grade = 'D'
else:
    grade = 'F'
print(f"分数 {score} 的等级是: {grade}")

四、 赋值运算符:给数据贴上标签

赋值运算符用于给变量赋值,Python提供了多种赋值运算符来简化代码。

4.1 基本赋值与复合赋值

实战案例4-6:赋值运算符的应用

# 基本赋值
x = 10
print(f"x = 10 → x = {x}")

# 多重赋值
a = b = c = 0  # 所有变量都指向同一个对象
print(f"a = b = c = 0 → a={a}, b={b}, c={c}")

# 多元赋值(解包赋值)
x, y, z = 1, 2, 3
print(f"x, y, z = 1, 2, 3 → x={x}, y={y}, z={z}")

# 交换两个变量的值(不需要临时变量)
x, y = 10, 20
print(f"交换前: x={x}, y={y}")
x, y = y, x  # 交换值
print(f"交换后: x={x}, y={y}")

# 复合赋值运算符
x = 5
x += 3  # 等价于 x = x + 3
print(f"x += 3 → x = {x}")  # 8

x -= 2  # 等价于 x = x - 2
print(f"x -= 2 → x = {x}")  # 6

x *= 4  # 等价于 x = x * 4
print(f"x *= 4 → x = {x}")  # 24

x //= 5  # 等价于 x = x // 5
print(f"x //= 5 → x = {x}")  # 4

x **= 3  # 等价于 x = x ** 3
print(f"x **= 3 → x = {x}")  # 64

# 与其他数据类型的复合运算
s = "Hello"
s += " World!"  # 字符串拼接
print(f's += " World!" → s = "{s}"')  # "Hello World!"

lst = [1, 2, 3]
lst += [4, 5]  # 列表扩展
print(f"lst += [4, 5] → lst = {lst}")  # [1, 2, 3, 4, 5]

4.2 海象运算符(Python 3.8+)

海象运算符(:=)允许在表达式内部进行赋值,可以简化某些代码模式。

实战案例4-7:海象运算符的应用

# 传统方式:需要在循环外和循环内重复计算或调用
while True:
    data = input("请输入数据 (输入quit退出): ")
    if data == "quit":
        break
    process_data(data)  # 处理数据的函数

# 使用海象运算符:更简洁
while (data := input("请输入数据 (输入quit退出): ")) != "quit":
    process_data(data)

# 在列表推导式中使用
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 传统方式:需要计算两次len(numbers)
if len(numbers) > 5:
    print(f"列表长度 {len(numbers)} 大于5")

# 使用海象运算符:只计算一次
if (n := len(numbers)) > 5:
    print(f"列表长度 {n} 大于5")

# 在正则表达式匹配中特别有用
import re
text = "今天是2023-10-15,明天是2023-10-16"
# 传统方式
match = re.search(r'\d{4}-\d{2}-\d{2}', text)
if match:
    date = match.group(0)
    print(f"找到日期: {date}")

# 使用海象运算符
if match := re.search(r'\d{4}-\d{2}-\d{2}', text):
    print(f"找到日期: {match.group(0)}")

# 处理返回None的函数调用
def get_config_value(key):
    # 模拟从配置中获取值,可能返回None
    config = {"host": "localhost", "port": 8080}
    return config.get(key)

# 传统方式
host = get_config_value("host")
if host is not None:
    print(f"主机: {host}")

# 使用海象运算符
if (host := get_config_value("host")) is not None:
    print(f"主机: {host}")

五、 逻辑运算符:组合条件判断

逻辑运算符用于组合多个条件,进行布尔逻辑运算。

5.1 基本逻辑运算

实战案例4-8:逻辑运算符的应用

# 基本逻辑运算
x = True
y = False

print(f"逻辑与: {x} and {y}{x and y}")  # False
print(f"逻辑或: {x} or {y}{x or y}")    # True
print(f"逻辑非: not {x}{not x}")        # False

# 实际应用:多条件判断
age = 25
has_license = True
has_car = False

# 可以开车条件:年龄≥18且有驾照
can_drive = age >= 18 and has_license
print(f"可以开车: {can_drive}")  # True

# 需要租车条件:可以开车但没有车
need_rental = can_drive and not has_car
print(f"需要租车: {need_rental}")  # True

# 复杂条件:年龄在18-65之间,有驾照,并且(有自己的车或者有租车预算)
has_rental_budget = True
can_go_roadtrip = (18 <= age <= 65) and has_license and (has_car or has_rental_budget)
print(f"可以自驾游: {can_go_roadtrip}")  # True

5.2 短路求值(Short-Circuit Evaluation)

Python的逻辑运算符支持短路求值,这在某些情况下非常有用且高效。

实战案例4-9:短路求值的应用

# and 短路:如果第一个表达式为False,不再计算第二个
def check_permission(user):
    print(f"检查用户 {user} 的权限...")
    return user == "admin"

user = "guest"
# 由于user != "admin",check_permission不会执行
result = user == "admin" and check_permission(user)
print(f"结果: {result}")

# or 短路:如果第一个表达式为True,不再计算第二个
def get_backup_data():
    print("从备份获取数据...")
    return "backup_data"

primary_data = None
# 使用or提供默认值
data = primary_data or get_backup_data()
print(f"获取到的数据: {data}")

# 实际应用:避免除零错误
def calculate_ratio(numerator, denominator):
    # 如果denominator为0,直接返回0,避免除零错误
    return denominator != 0 and numerator / denominator

print(f"10/5 = {calculate_ratio(10, 5)}")  # 2.0
print(f"10/0 = {calculate_ratio(10, 0)}")  # False

# 安全访问嵌套属性
class User:
    def __init__(self, profile=None):
        self.profile = profile

class Profile:
    def __init__(self, address=None):
        self.address = address

user = User(Profile("北京"))
# 安全获取地址,避免AttributeError
address = user.profile and user.profile.address
print(f"用户地址: {address}")

# 使用短路求值设置默认值
default_address = "地址未知"
address = (user.profile and user.profile.address) or default_address
print(f"用户地址: {address}")

六、 位运算符:底层二进制操作

位运算符直接对整数的二进制位进行操作,常用于底层编程、性能优化和某些特定算法。

6.1 基本位运算

实战案例4-10:位运算符的应用

# 二进制表示
a = 0b1100  # 12
b = 0b1010  # 10

print(f"a = {a} (二进制: {bin(a)})")
print(f"b = {b} (二进制: {bin(b)})")

# 位与运算:两位都为1时结果为1
bitwise_and = a & b  # 0b1000 → 8
print(f"位与: {a} & {b} = {bitwise_and} (二进制: {bin(bitwise_and)})")

# 位或运算:有一位为1时结果为1
bitwise_or = a | b  # 0b1110 → 14
print(f"位或: {a} | {b} = {bitwise_or} (二进制: {bin(bitwise_or)})")

# 位异或运算:两位不同时结果为1
bitwise_xor = a ^ b  # 0b0110 → 6
print(f"位异或: {a} ^ {b} = {bitwise_xor} (二进制: {bin(bitwise_xor)})")

# 位取反运算:所有位取反
bitwise_not = ~a  # 结果取决于整数表示(补码)
print(f"位取反: ~{a} = {bitwise_not} (二进制: {bin(bitwise_not)})")

# 左移位运算:所有位向左移动,右侧补0
left_shift = a << 2  # 0b110000 → 48
print(f"左移位: {a} << 2 = {left_shift} (二进制: {bin(left_shift)})")

# 右移位运算:所有位向右移动,左侧补符号位
right_shift = a >> 2  # 0b0011 → 3
print(f"右移位: {a} >> 2 = {right_shift} (二进制: {bin(right_shift)})")

6.2 位运算的实际应用

实战案例4-11:位运算的实用场景

# 1. 权限系统:使用位掩码表示和检查权限
READ_PERMISSION = 0b0001  # 1
WRITE_PERMISSION = 0b0010  # 2
EXECUTE_PERMISSION = 0b0100  # 4
ADMIN_PERMISSION = 0b1000  # 8

# 用户权限:可读可写
user_permissions = READ_PERMISSION | WRITE_PERMISSION  # 0b0011 → 3

# 检查权限
can_read = user_permissions & READ_PERMISSION != 0
can_write = user_permissions & WRITE_PERMISSION != 0
can_execute = user_permissions & EXECUTE_PERMISSION != 0
is_admin = user_permissions & ADMIN_PERMISSION != 0

print(f"可读: {can_read}, 可写: {can_write}, 可执行: {can_execute}, 管理员: {is_admin}")

# 添加权限
user_permissions |= EXECUTE_PERMISSION  # 添加执行权限
print(f"添加执行权限后: {bin(user_permissions)}")

# 移除权限
user_permissions &= ~WRITE_PERMISSION  # 移除写权限
print(f"移除写权限后: {bin(user_permissions)}")

# 2. 奇偶判断:使用位与运算
def is_even(n):
    return n & 1 == 0

print(f"5是偶数: {is_even(5)}")  # False
print(f"8是偶数: {is_even(8)}")  # True

# 3. 乘除2的幂:使用移位运算(性能更高)
n = 10
print(f"{n} * 4 = {n << 2}")  # 左移2位相当于乘4
print(f"{n} / 2 = {n >> 1}")  # 右移1位相当于除2(整数除法)

# 4. 交换两个数:使用异或运算(不需要临时变量)
x, y = 5, 7
print(f"交换前: x={x}, y={y}")
x = x ^ y
y = x ^ y  # y = (x^y)^y = x
x = x ^ y  # x = (x^y)^x = y
print(f"交换后: x={x}, y={y}")

七、 身份运算符与成员运算符

7.1 身份运算符(is, is not)

身份运算符用于比较两个对象的内存地址是否相同,即是否是同一个对象。

实战案例4-12:身份运算符的应用

# is 与 == 的区别
a = [1, 2, 3]
b = a  # b和a指向同一个列表对象
c = [1, 2, 3]  # c是另一个列表对象,值与a相同

print(f"a == b: {a == b}")  # True (值相等)
print(f"a is b: {a is b}")  # True (是同一个对象)

print(f"a == c: {a == c}")  # True (值相等)
print(f"a is c: {a is c}")  # False (不是同一个对象)

# 小整数池(Python的优化)
x = 256
y = 256
print(f"x is y (256): {x is y}")  # True (小整数池)

x = 257
y = 257
print(f"x is y (257): {x is y}")  # False (不在小整数池)

# 与None比较时应该使用is
value = None
# 正确的方式
if value is None:
    print("值是None")
    
# 错误的方式(虽然通常能工作,但不推荐)
if value == None:
    print("值等于None")

7.2 成员运算符(in, not in)

成员运算符用于测试一个值是否存在于序列(如字符串、列表、元组、字典、集合)中。

实战案例4-13:成员运算符的应用

# 字符串中的成员测试
s = "Hello, World!"
print(f"'Hello' in '{s}': {'Hello' in s}")  # True
print(f"'Python' not in '{s}': {'Python' not in s}")  # True

# 列表中的成员测试
fruits = ["apple", "banana", "orange"]
print(f"'apple' in {fruits}: {'apple' in fruits}")  # True
print(f"'grape' not in {fruits}: {'grape' not in fruits}")  # True

# 字典中的成员测试(检查键)
person = {"name": "Alice", "age": 25, "city": "Beijing"}
print(f"'name' in {person}: {'name' in person}")  # True
print(f"'Alice' in {person}: {'Alice' in person}")  # False (字典成员测试检查键,不是值)

# 集合中的成员测试(非常高效)
primes = {2, 3, 5, 7, 11, 13}
print(f"7 in {primes}: {7 in primes}")  # True

# 实际应用:检查用户名是否可用
existing_usernames = {"alice", "bob", "charlie", "dave"}
new_username = "eve"

if new_username not in existing_usernames:
    print(f"用户名 '{new_username}' 可用")
else:
    print(f"用户名 '{new_username}' 已存在")

# 检查文件扩展名
filename = "document.pdf"
if filename.endswith(('.pdf', '.doc', '.docx')):
    print(f"'{filename}' 是文档文件")
else:
    print(f"'{filename}' 不是文档文件")

八、 运算符优先级与结合性

当表达式中包含多个运算符时,运算符的优先级和结合性决定了运算的执行顺序。

8.1 运算符优先级表

从最高优先级到最低优先级:

运算符 描述
() 括号(最高优先级)
** 幂运算
+x, -x, ~x 正号、负号、按位取反
*, /, //, % 乘、除、整除、取模
+, - 加、减
<<, >> 位左移、位右移
& 位与
^ 位异或
| 位或
==, !=, >, >=, <, <=, is, is not, in, not in 比较、身份、成员运算符
not 逻辑非
and 逻辑与
or 逻辑或
:= 海象运算符(最低优先级)

8.2 优先级实战

实战案例4-14:运算符优先级分析

# 复杂表达式分析
result = 5 + 3 * 2 ** 2 / 4 - 1
# 计算步骤:
# 1. 2**2 = 4
# 2. 3*4 = 12
# 3. 12/4 = 3.0
# 4. 5+3.0 = 8.0
# 5. 8.0-1 = 7.0
print(f"5 + 3 * 2 ** 2 / 4 - 1 = {result}")  # 7.0

# 使用括号明确优先级
result = (5 + 3) * (2 ** 2) / (4 - 1)
# 计算步骤:
# 1. 5+3=8
# 2. 2**2=4
# 3. 4-1=3
# 4. 8*4=32
# 5. 32/3≈10.666
print(f"(5 + 3) * (2 ** 2) / (4 - 1) = {result}")  # 10.666...

# 逻辑运算符优先级:not > and > or
x, y, z = True, False, True
result = not x and y or z
# 计算步骤:
# 1. not x = False
# 2. False and y = False
# 3. False or z = True
print(f"not {x} and {y} or {z} = {result}")  # True

# 使用括号明确逻辑优先级
result = (not x) and (y or z)
# 计算步骤:
# 1. not x = False
# 2. y or z = True
# 3. False and True = False
print(f"(not {x}) and ({y} or {z}) = {result}")  # False

8.3 结合性

当多个相同优先级的运算符出现在表达式中时,结合性决定了运算的顺序。

  • 大多数运算符是左结合的:从左到右计算

    • a + b + c(a + b) + c
    • a * b * c(a * b) * c
  • 少数运算符是右结合的:从右到左计算

    • a ** b ** ca ** (b ** c)
    • a = b = ca = (b = c)

实战案例4-15:结合性分析

# 幂运算是右结合
result = 2 ** 3 ** 2  # 等价于 2 ** (3 ** 2) = 2 ** 9 = 512
print(f"2 ** 3 ** 2 = {result}")  # 512

# 赋值运算是右结合
a = b = c = 5  # 等价于 a = (b = (c = 5))
print(f"a={a}, b={b}, c={c}")  # 都是5

# 比较运算符是左结合,但实际上是链式比较
# 1 < 2 < 3 等价于 (1 < 2) and (2 < 3)
result = 1 < 2 < 3  # True
print(f"1 < 2 < 3 = {result}")  # True

九、 综合实战:智能计算器增强版

现在,让我们创建一个增强版的智能计算器,综合运用本章所学的各种运算符。

项目目标:

  • 支持基本算术运算
  • 支持位运算
  • 支持比较运算和逻辑运算
  • 支持变量存储和引用
  • 提供运算历史记录

代码实现:

def enhanced_calculator():
    """增强版智能计算器"""
    print("=== 增强版智能计算器 ===")
    print("支持功能:")
    print("- 基本算术: +, -, *, /, //, %, **")
    print("- 位运算: &, |, ^, ~, <<, >>")
    print("- 比较运算: ==, !=, >, <, >=, <=")
    print("- 逻辑运算: and, or, not")
    print("- 变量赋值: 使用 = 赋值,如 x = 5")
    print("- 变量引用: 直接使用变量名")
    print("- 查看历史: 输入 'history'")
    print("- 退出: 输入 'quit'")
    
    variables = {}  # 存储变量
    history = []    # 存储计算历史
    
    while True:
        try:
            expression = input("\n请输入表达式: ").strip()
            
            if expression.lower() == 'quit':
                print("感谢使用计算器!")
                break
                
            if expression.lower() == 'history':
                print("\n计算历史:")
                for i, item in enumerate(history, 1):
                    print(f"{i}. {item}")
                continue
                
            if not expression:
                continue
                
            # 处理变量赋值
            if '=' in expression:
                parts = expression.split('=', 1)
                var_name = parts[0].strip()
                expr = parts[1].strip()
                
                if not var_name.isidentifier():
                    print(f"错误: '{var_name}' 不是有效的变量名")
                    continue
                    
                # 计算表达式值
                result = evaluate_expression(expr, variables)
                variables[var_name] = result
                history_entry = f"{var_name} = {expr} = {result}"
                history.append(history_entry)
                print(f"{var_name} = {result}")
                
            else:
                # 计算表达式值
                result = evaluate_expression(expression, variables)
                history_entry = f"{expression} = {result}"
                history.append(history_entry)
                print(f"结果: {result}")
                
        except Exception as e:
            print(f"错误: {e}")

def evaluate_expression(expr, variables):
    """计算表达式的值"""
    # 安全检查:禁止使用危险函数
    for func in ['__', 'import', 'open', 'eval', 'exec']:
        if func in expr:
            raise ValueError("表达式包含不安全内容")
    
    # 替换变量名
    for var_name in sorted(variables.keys(), key=len, reverse=True):
        if var_name in expr:
            expr = expr.replace(var_name, str(variables[var_name]))
    
    # 使用eval计算表达式(在实际应用中应考虑更安全的方式)
    try:
        return eval(expr, {"__builtins__": None}, {})
    except:
        # 如果eval失败,尝试更简单的解析
        return simple_eval(expr)

def simple_eval(expr):
    """简单的表达式求值(用于演示,实际应用需要更完整的解析器)"""
    # 这里只实现非常简单的解析作为示例
    # 实际应用中应该使用ast模块或编写完整的解析器
    if expr.isdigit():
        return int(expr)
    try:
        return float(expr)
    except ValueError:
        pass
        
    # 处理简单的二元运算
    for op in ['+', '-', '*', '/', '//', '%', '**', '&', '|', '^', '<<', '>>']:
        if op in expr:
            parts = expr.split(op, 1)
            left = simple_eval(parts[0].strip())
            right = simple_eval(parts[1].strip())
            
            if op == '+': return left + right
            if op == '-': return left - right
            if op == '*': return left * right
            if op == '/': return left / right
            if op == '//': return left // right
            if op == '%': return left % right
            if op == '**': return left ** right
            if op == '&': return left & right
            if op == '|': return left | right
            if op == '^': return left ^ right
            if op == '<<': return left << right
            if op == '>>': return left >> right
    
    raise ValueError(f"无法解析表达式: {expr}")

# 运行计算器
if __name__ == "__main__":
    enhanced_calculator()

运行示例:

=== 增强版智能计算器 ===
支持功能:
- 基本算术: +, -, *, /, //, %, **
- 位运算: &, |, ^, ~, <<, >>
- 比较运算: ==, !=, >, <, >=, <=
- 逻辑运算: and, or, not
- 变量赋值: 使用 = 赋值,如 x = 5
- 变量引用: 直接使用变量名
- 查看历史: 输入 'history'
- 退出: 输入 'quit'

请输入表达式: x = 10 + 5 * 2
x = 20

请输入表达式: y = x ** 2
y = 400

请输入表达式: x & y
结果: 0

请输入表达式: x > 15 and y < 500
结果: True

请输入表达式: history

计算历史:
1. x = 10 + 5 * 2 = 20
2. y = x ** 2 = 400
3. x & y = 0
4. x > 15 and y < 500 = True

请输入表达式: quit
感谢使用计算器!

总结与思考

通过本篇文章的深入学习,我们全面掌握了Python中的各类运算符及其应用:

  1. 算术运算符:用于数学计算,包括基本的加减乘除和幂运算
  2. 比较运算符:用于值比较,返回布尔结果,支持链式比较
  3. 赋值运算符:用于变量赋值,包括基本赋值和复合赋值
  4. 逻辑运算符:用于组合条件,支持短路求值优化
  5. 位运算符:用于底层位操作,在特定场景下非常有用
  6. 身份运算符:用于对象标识比较,特别适用于与None比较
  7. 成员运算符:用于序列成员测试,简洁高效
  8. 运算符优先级与结合性:决定了复杂表达式的计算顺序
  9. 海象运算符(Python 3.8+):在表达式内进行赋值,简化代码

思考题:

  1. 在什么情况下应该使用 is 而不是 ==?为什么与 None 比较时推荐使用 is
  2. 短路求值除了提高性能外,还有什么其他实际应用场景?
  3. 如何安全地处理用户输入的数学表达式,避免使用 eval() 的安全风险?
  4. 位运算在哪些实际应用场景中比算术运算更有优势?
  5. 海象运算符虽然强大,但过度使用可能会降低代码可读性。你认为在什么情况下应该使用海象运算符?

更多推荐