# Python 运算符

## 学习目标
- 掌握 Python 的七种运算符类别
- 理解运算符优先级
- 学会在实际编程中灵活运用各种运算符

---

## 一、运算符概览

Python 提供了丰富的运算符，主要分为以下七类：

| 类别 | 运算符 | 示例 |
|------|--------|------|
| 算术运算符 | `+` `-` `*` `/` `//` `%` `**` | `a + b` |
| 比较运算符 | `==` `!=` `>` `<` `>=` `<=` | `a > b` |
| 赋值运算符 | `=` `+=` `-=` `*=` `/=` 等 | `a += 1` |
| 逻辑运算符 | `and` `or` `not` | `a and b` |
| 位运算符 | `&` `\|` `^` `~` `<<` `>>` | `a & b` |
| 成员运算符 | `in` `not in` | `x in list` |
| 身份运算符 | `is` `is not` | `a is b` |

---

## 二、算术运算符

```python
a = 17
b = 5

print(f"a = {a}, b = {b}")
print(f"a + b = {a + b}")      # 加法: 22
print(f"a - b = {a - b}")      # 减法: 12
print(f"a * b = {a * b}")      # 乘法: 85
print(f"a / b = {a / b}")      # 除法: 3.4（总是返回 float）
print(f"a // b = {a // b}")    # 整除: 3（向下取整）
print(f"a % b = {a % b}")      # 取模: 2
print(f"a ** b = {a ** b}")    # 幂运算: 1419857
```

### 特殊除法示例

```python
# 负数整除（向负无穷取整）
print(-17 // 5)    # -4
print(17 // -5)    # -4

# divmod() 同时获取商和余数
print(divmod(17, 5))    # (3, 2)

# 混合运算类型
print(5 + 3.0)     # 8.0（int + float = float）
```

---

## 三、比较运算符

```python
x = 10
y = 20

print(x == y)     # False（等于）
print(x != y)     # True（不等于）
print(x > y)      # False（大于）
print(x < y)      # True（小于）
print(x >= 10)    # True（大于等于）
print(x <= 9)     # False（小于等于）
```

### 链式比较

```python
# Python 支持链式比较，等价于 0 < x and x < 100
x = 50
print(0 < x < 100)       # True
print(0 < x < 30)        # False
print(100 > x > 25)      # True
```

### 字符串比较

```python
# 按字典序（Unicode 码点）比较
print("apple" < "banana")   # True
print("Z" > "a")            # False（大写字母 Unicode 码小于小写）
print("abc" == "abc")       # True
```

---

## 四、赋值运算符

```python
x = 10          # 基本赋值

x += 5          # x = x + 5，x 变为 15
x -= 3          # x = x - 3，x 变为 12
x *= 2          # x = x * 2，x 变为 24
x /= 4          # x = x / 4，x 变为 6.0
x //= 2         # x = x // 2，x 变为 3.0
x %= 2          # x = x % 2，x 变为 1.0

print(x)        # 1.0
```

### 海象运算符（:=）Python 3.8+

```python
# 在表达式内部赋值
n = 10
if (m := n * 2) > 15:
    print(f"m = {m}")   # m = 20

# 在 while 中使用
while (line := input("输入 (q 退出): ")) != "q":
    print(f"你输入了: {line}")
```

### 多重赋值与序列解包

```python
# 同时赋值多个变量
a, b, c = 1, 2, 3
print(a, b, c)   # 1 2 3

# 交换变量
x, y = 10, 20
x, y = y, x      # 无需临时变量
print(x, y)      # 20 10

# 带 * 的解包
first, *rest = [1, 2, 3, 4, 5]
print(first)     # 1
print(rest)      # [2, 3, 4, 5]
```

---

## 五、逻辑运算符

```python
a = True
b = False

print(a and b)    # False（全真为真）
print(a or b)     # True（有真为真）
print(not a)      # False（取反）
```

### 短路求值

```python
# and：左边为 False，直接返回左边值，不计算右边
def side_effect():
    print("副作用执行了")
    return True

result = False and side_effect()   # 不会调用 side_effect()
print(result)   # False

# or：左边为 True，直接返回左边值
result = True or side_effect()     # 不会调用 side_effect()
print(result)   # True
```

### 非布尔值的逻辑运算

```python
# and 返回第一个为假的值，或最后一个值
print(3 and 5)        # 5
print(0 and 5)        # 0
print("hello" and []) # []

# or 返回第一个为真的值
print(3 or 5)         # 3
print(0 or 5)         # 5
print("" or "hello")  # "hello"

# 实用技巧：设置默认值
name = "" or "匿名"
print(name)   # 匿名
```

---

## 六、位运算符

```python
a = 0b1010   # 10
b = 0b1100   # 12

print(f"a = {a} ({bin(a)})")
print(f"b = {b} ({bin(b)})")

print(f"a & b = {a & b} ({bin(a & b)})")    # 按位与: 8 (0b1000)
print(f"a | b = {a | b} ({bin(a | b)})")    # 按位或: 14 (0b1110)
print(f"a ^ b = {a ^ b} ({bin(a ^ b)})")    # 按位异或: 6 (0b0110)
print(f"~a = {~a} ({bin(~a)})")              # 按位取反: -11
print(f"a << 2 = {a << 2} ({bin(a << 2)})") # 左移: 40 (0b101000)
print(f"a >> 2 = {a >> 2} ({bin(a >> 2)})") # 右移: 2 (0b10)
```

### 位运算实用场景

```python
# 判断奇偶
n = 7
print("奇数" if n & 1 else "偶数")   # 奇数

# 交换两个数（不使用临时变量）
x, y = 10, 20
x = x ^ y
y = x ^ y
x = x ^ y
print(x, y)   # 20 10

# 权限控制（使用位标志）
READ = 4    # 0b100
WRITE = 2   # 0b010
EXECUTE = 1 # 0b001

permission = READ | WRITE   # 读写权限
print(permission)           # 6
print(bool(permission & READ))    # True（有读权限）
print(bool(permission & EXECUTE)) # False（无执行权限）
```

---

## 七、成员运算符

```python
# 列表
fruits = ["apple", "banana", "cherry"]
print("apple" in fruits)        # True
print("grape" not in fruits)    # True

# 字符串
print("Py" in "Python")         # True
print("xyz" not in "abc")       # True

# 字典（判断 key）
user = {"name": "Alice", "age": 25}
print("name" in user)           # True
print("Alice" in user)          # False（不是判断 value）
print("Alice" in user.values()) # True
```

---

## 八、身份运算符

```python
# is 判断是否是同一个对象（内存地址相同）
a = [1, 2, 3]
b = a
c = [1, 2, 3]

print(a is b)      # True（同一对象）
print(a is c)      # False（值相同，但不是同一对象）
print(a == c)      # True（值相等）

# 小整数缓存（-5 ~ 256）
x = 100
y = 100
print(x is y)      # True（缓存复用）

m = 1000
n = 1000
print(m is n)      # False（大整数不缓存）

# None 判断必须用 is
value = None
print(value is None)       # True
print(value is not None)   # False
```

---

## 九、运算符优先级

从高到低排列：

| 优先级 | 运算符 |
|--------|--------|
| 1（最高）| `()` 括号 |
| 2 | `**` 幂运算 |
| 3 | `+x` `-x` `~x` 正负、按位取反 |
| 4 | `*` `/` `//` `%` `@` |
| 5 | `+` `-` |
| 6 | `<<` `>>` |
| 7 | `&` |
| 8 | `^` |
| 9 | `\|` |
| 10 | `==` `!=` `>` `<` `>=` `<=` `is` `in` 等 |
| 11 | `not` |
| 12 | `and` |
| 13（最低）| `or` |

```python
# 优先级示例
result = 2 + 3 * 4        # 14（先乘后加）
result = (2 + 3) * 4      # 20（括号优先）
result = 2 ** 3 ** 2      # 512（从右到左: 2^(3^2) = 2^9）
result = not True or False and True   # False（not > and > or）
```

---

## 十、综合示例

```python
"""
简易计算器程序
"""

print("=" * 30)
print("      简 易 计 算 器")
print("=" * 30)

num1 = float(input("请输入第一个数: "))
operator = input("请输入运算符 (+ - * / // % **): ")
num2 = float(input("请输入第二个数: "))

if operator == "+":
    result = num1 + num2
elif operator == "-":
    result = num1 - num2
elif operator == "*":
    result = num1 * num2
elif operator == "/":
    result = num1 / num2
elif operator == "//":
    result = num1 // num2
elif operator == "%":
    result = num1 % num2
elif operator == "**":
    result = num1 ** num2
else:
    result = None
    print("无效的运算符")

if result is not None:
    print(f"\n结果: {num1} {operator} {num2} = {result}")
```

---

## 小结

- 算术运算符：`+` `-` `*` `/` `//` `%` `**`
- 比较运算符支持链式写法，如 `0 < x < 100`
- 赋值运算符支持复合形式，如 `+=` `*=`，以及海象运算符 `:=`
- 逻辑运算符具有短路求值特性
- `is` 判断对象身份，`==` 判断值相等
- 不确定优先级时，使用括号 `()` 明确表达意图

---

## 练习

1. 输入一个年份，判断是否为闰年（能被 4 整除但不能被 100 整除，或能被 400 整除）。
2. 使用位运算符实现：判断一个数的第 n 位是否为 1。
3. 输入三个数，输出其中的最大值和最小值（不使用 `max()` / `min()`）。
4. 解释 `a is b` 和 `a == b` 的区别，并举例说明。

