首页 / 知识库 / 0基础入门-阅读资料 / 0基础-python入门到精通

第 3 章 变量、表达式与运算符

3.1 变量赋值与命名规则

Python 中变量不需要声明类型,赋值即创建:

name = "Alice"     # 字符串
age = 30           # 整数
height = 1.68      # 浮点数
is_student = True  # 布尔

# 多重赋值
x = y = z = 0

# 解包赋值
a, b, c = 1, 2, 3

# 交换变量 — Python 特有的优雅写法
a, b = b, a

命名规则

  1. 只能包含字母、数字、下划线,不能以数字开头
  2. 区分大小写:nameName 是不同变量
  3. 不能使用关键字(ifforclass 等)
# 查看所有关键字
import keyword
print(keyword.kwlist)
# ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
#  'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except',
#  'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
#  'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return',
#  'try', 'while', 'with', 'yield']

命名风格

# 推荐的命名风格(PEP 8)
user_name = "Bob"          # 变量:snake_case
MAX_RETRIES = 3            # 常量:UPPER_SNAKE_CASE
class UserProfile: pass    # 类名:PascalCase
def get_user(): pass       # 函数:snake_case
_private_var = "secret"    # 私有:前缀下划线

3.2 动态类型与变量引用模型

Python 变量是标签(引用),不是盒子。变量名绑定到对象,而非存储值。

a = [1, 2, 3]
b = a          # b 和 a 指向同一个列表对象
b.append(4)
print(a)       # [1, 2, 3, 4] — a 也变了!

# 验证:id() 返回对象的内存地址
print(id(a) == id(b))  # True — 同一个对象

图示理解

a ──→ [1, 2, 3, 4]  ←── b     # a 和 b 是两个标签,贴在同一个对象上

重新赋值 vs 修改对象

a = [1, 2, 3]
b = a

# 重新赋值 — b 指向新对象,a 不变
b = [4, 5, 6]
print(a)  # [1, 2, 3]

# 修改对象 — a 和 b 指向同一对象,都受影响
a = [1, 2, 3]
b = a
b[0] = 99
print(a)  # [99, 2, 3]

动态类型

变量可以随时绑定到不同类型的对象:

x = 42          # int
x = "hello"     # str — 合法!类型跟着值走
x = [1, 2, 3]   # list — 又变了

# type() 查看当前类型
print(type(x))  # <class 'list'>

可变与不可变对象

不可变(immutable)可变(mutable)
int, float, boollist
str, tupledict
frozenset, bytesset, bytearray
# 不可变对象 — "修改"实际上是创建新对象
a = "hello"
print(id(a))   # 比如 140234567890
a = a + " world"
print(id(a))   # 不同了!新对象

# 可变对象 — 原地修改
lst = [1, 2, 3]
print(id(lst))  # 比如 140234567900
lst.append(4)
print(id(lst))  # 不变!同一个对象

小整数缓存

CPython 优化:-5 到 256 的整数会被缓存复用:

a = 256
b = 256
print(a is b)  # True — 同一个对象(缓存)

a = 257
b = 257
print(a is b)  # False — 不同对象(注意:在 REPL 中可能为 True)

3.3 算术运算符

# 基本运算
10 + 3     # 13    加
10 - 3     # 7     减
10 * 3     # 30    乘
10 / 3     # 3.333... 真除法(结果总是 float)
10 // 3    # 3     整除(向下取整)
10 % 3     # 1     取模
10 ** 3    # 1000  幂运算

# 整除的"向下取整"特性
-7 // 2    # -4(不是 -3!向负无穷方向取整)
7 // -2    # -4

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

# abs — 绝对值
abs(-42)   # 42

# round — 四舍五入(银行家舍入法)
round(2.5)    # 2(不是 3!四舍六入五取偶)
round(3.5)    # 4
round(3.14159, 2)  # 3.14

类型提升规则

# int + float → float
3 + 2.0        # 5.0

# int + complex → complex
3 + 2j         # (3+2j)

# bool 参与运算时当作 int
True + 1       # 2
False * 10     # 0

3.4 比较运算符与链式比较

# 基本比较
3 == 3     # True
3 != 4     # True
3 < 5      # True
3 > 5      # False
3 <= 3     # True
3 >= 4     # False

# 链式比较 — Python 特色!
x = 5
1 < x < 10        # True,等价于 1 < x and x < 10
1 < x < 3         # False
1 <= x <= 5 <= 10 # True

== vs is

a = [1, 2, 3]
b = [1, 2, 3]

a == b    # True  — 值相等
a is b    # False — 不是同一个对象

a = b
a is b    # True  — 现在是同一个对象了

# 经验法则:
# == 比较值,is 比较身份(内存地址)
# 只有和 None 比较时才用 is

不同类型的比较

# 数字之间可以比较
42 == 42.0        # True
True == 1         # True

# 字符串按字典序比较
"apple" < "banana"    # True
"abc" < "abd"         # True

# 不同类型之间大多数情况不能比较
# "abc" < 123         # TypeError(Python 3)

3.5 逻辑运算符:and、or、not 及短路求值

True and False   # False
True or False    # True
not True         # False

短路求值(Short-circuit Evaluation)

andor 不一定返回 True/False,而是返回决定结果的那个值:

# and: 如果第一个为假,直接返回第一个;否则返回第二个
0 and "hello"       # 0(第一个为假,短路)
"hello" and "world" # "world"(第一个为真,返回第二个)
"" and "world"      # ""(空字符串为假)

# or: 如果第一个为真,直接返回第一个;否则返回第二个
0 or "hello"        # "hello"(第一个为假,返回第二个)
"hello" or "world"  # "hello"(第一个为真,短路)
"" or "default"     # "default"

实用技巧

# 提供默认值(被 := 海象运算符和 or 取代的场景)
name = user_input or "Anonymous"

# 条件执行
debug = True
debug and print("调试信息")  # debug 为 True 时才打印

# 等价于
if debug:
    print("调试信息")

布尔运算优先级

not > and > or

# not > and > or
True or False and not False
# 等价于: True or (False and (not False))
# = True or (False and True)
# = True or False
# = True

3.6 位运算符

用于对整数的二进制位进行操作:

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

a & b    # 0b1000 = 8    按位与
a | b    # 0b1110 = 14   按位或
a ^ b    # 0b0110 = 6    按位异或
~a       # -13           按位取反(补码)
a << 2   # 0b110000 = 48 左移
a >> 2   # 0b0011 = 3    右移

# 格式化查看二进制
print(f"{a:08b}")  # 00001100
print(f"{b:08b}")  # 00001010

常见应用

# 判断奇偶
n = 7
is_odd = n & 1       # 1 → 奇数
is_even = not (n & 1)  # False → 不是偶数

# 标志位
READ    = 0b001  # 1
WRITE   = 0b010  # 2
EXECUTE = 0b100  # 4

permission = READ | WRITE       # 0b011 = 3
has_read = permission & READ    # 0b001 = 1 → True
has_exec = permission & EXECUTE # 0b000 = 0 → False

# 交换两个整数(不用临时变量,但可读性差,不推荐)
a = a ^ b
b = a ^ b
a = a ^ b

3.7 赋值运算符与海象运算符

增强赋值

x = 10
x += 3    # x = x + 3 → 13
x -= 2    # 11
x *= 4    # 44
x /= 11   # 4.0
x //= 3   # 1.0
x **= 3   # 1.0
x %= 7    # 1.0

# 对于可变对象,+= 是原地修改
lst = [1, 2]
original_id = id(lst)
lst += [3, 4]              # 调用 __iadd__,原地扩展
print(id(lst) == original_id)  # True

# 对于不可变对象,+= 创建新对象
s = "hello"
original_id = id(s)
s += " world"
print(id(s) == original_id)   # False

海象运算符 :=(Python 3.8+)

在表达式内部赋值,避免重复计算:

# 不用海象运算符
line = input("请输入: ")
while line != "quit":
    print(f"你输入了: {line}")
    line = input("请输入: ")

# 用海象运算符 — 更简洁
while (line := input("请输入: ")) != "quit":
    print(f"你输入了: {line}")
# 在条件判断中避免重复计算
data = [1, 5, 3, 8, 2, 9, 4, 7]

# 不用海象运算符
results = []
for x in data:
    y = x ** 2 + x
    if y > 20:
        results.append(y)

# 用海象运算符
results = [y for x in data if (y := x ** 2 + x) > 20]
print(results)  # [30, 72, 90, 56]
# 在正则匹配中
import re
text = "Phone: 138-1234-5678"

# 不用海象运算符
match = re.search(r"\d{3}-\d{4}-\d{4}", text)
if match:
    print(f"找到号码: {match.group()}")

# 用海象运算符
if match := re.search(r"\d{3}-\d{4}-\d{4}", text):
    print(f"找到号码: {match.group()}")

3.8 运算符优先级

从高到低排列(同一行优先级相同):

优先级运算符说明
最高()括号
**幂运算
+x, -x, ~x一元运算
*, /, //, %乘除
+, -加减
<<, >>位移
&按位与
^按位异或
|按位或
==, !=, <, >, <=, >=, is, in比较
not逻辑非
and逻辑与
最低or逻辑或

实用建议:不要死记优先级,多加括号让代码更清晰:

# 不推荐:依赖优先级
result = a + b * c ** 2 > d and e or f

# 推荐:用括号明确意图
result = ((a + (b * (c ** 2))) > d) and e) or f

# 或者拆成多行
power = c ** 2
product = b * power
is_greater = (a + product) > d
result = (is_greater and e) or f

本章小结:Python 的变量是引用而非容器,理解这一点对避免可变对象的陷阱至关重要。运算符方面,链式比较、短路求值、海象运算符是 Python 的独特特性,善用它们能写出更简洁的代码。