1. 运算符是什么
运算符是参与运算的符号。例如,+ 可以做加法,== 可以比较两个值是否相等,and 可以组合两个条件。
1price = 302quantity = 234total = price * quantity5print(total)
这里的 * 是运算符,price 和 quantity 是操作数。Python 先根据运算符的规则计算右侧表达式,再把结果赋给 total。
运算符不只用于数字。字符串、列表、字典等对象也可以参与某些运算,但具体结果取决于对象支持的操作。
2. 算术运算符
算术运算符用于做数学计算:
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 | 7 + 2 | 9 |
- | 减法 | 7 - 2 | 5 |
* | 乘法 | 7 * 2 | 14 |
/ | 除法 | 7 / 2 | 3.5 |
// | 整除 | 7 // 2 | 3 |
% | 取余 | 7 % 2 | 1 |
** | 乘方 | 7 ** 2 | 49 |
01left = 702right = 20304print(left + right) # 905print(left - right) # 506print(left * right) # 1407print(left / right) # 3.508print(left // right) # 309print(left % right) # 110print(left ** right) # 49
/ 的结果总是普通除法结果,通常是 float。// 表示向下取整的整除,不是简单地把小数部分截掉,负数参与运算时尤其要注意:
1print(7 // 2) # 32print(-7 // 2) # -4,结果向负无穷取整3print(-7 % 2) # 1
% 经常用于判断奇偶、循环取值和按固定数量分组:
1number = 1823if number % 2 == 0:4print("这是偶数")5else:6print("这是奇数")
字符串也可以使用 + 拼接,使用 * 重复:
1title = "Python" + " 运算符"2line = "-" * 20345print(title) # Python 运算符6print(line) # --------------------
但不同类型不能随意相加。数字和字符串拼接时,要使用 str() 或 f-string:
1age = 1823print("年龄:" + str(age))4print(f"年龄:{age}")5# print("年龄:" + age) # TypeError
3. 比较运算符
比较运算符用于判断两个值的关系,结果一定是布尔值 True 或 False:
| 运算符 | 含义 | 示例 |
|---|---|---|
== | 值相等 | age == 18 |
!= | 值不相等 | age != 18 |
> | 大于 | score > 60 |
< | 小于 | score < 60 |
>= | 大于或等于 | score >= 60 |
<= | 小于或等于 | score <= 60 |
1score = 8223print(score >= 60) # True4print(score == 100) # False5print(score != 0) # True
== 是比较运算,判断两边的值是否相等;= 是赋值运算,把右边的结果绑定给左边的变量:
1age = 182is_adult = age >= 1834print(is_adult) # True
Python 不会像某些语言那样,把字符串 "18" 自动转换成数字 18 再比较。比较不同类型的值时,应该先判断它们是否真的具有可比较的含义:
1print(1 == 1.0) # True,整数和浮点数按数值比较2print(1 == True) # True,bool 是 int 的特殊子类3print(1 == "1") # False,不会把字符串自动转换成整数45# print(1 < "2") # TypeError:数字和字符串不能直接比较大小
这里的 1 == 1.0 可以直接得到 True,是因为 Python 对兼容的数字类型使用数值语义进行比较;这不代表变量本身被永久转换成了另一种类型。True 和 False 也属于布尔类型,只是它们在 Python 的类型体系中分别对应数值 1 和 0,因此不建议把布尔值和数字混在业务条件中比较。
如果数据来自表单、命令行或 HTTP 请求,它通常先以字符串出现,需要显式转换后再比较:
1age_text = "18"2age = int(age_text)34if age >= 18:5print("已成年")
显式转换能让代码清楚表达意图,也能让无效输入在转换时及时暴露,而不是依赖不明显的类型规则。
字符串可以按字典顺序比较,列表也可以从前往后比较元素,但这类比较必须符合业务含义,不要只因为语法能够运行就认为结果一定符合需求:
1print("apple" < "banana") # True2print([1, 2] == [1, 2]) # True
4. 逻辑运算符
逻辑运算符用于组合多个条件:
| 运算符 | 含义 | 说明 |
|---|---|---|
and | 并且 | 两边都为真,结果才为真 |
or | 或者 | 至少一边为真,结果就为真 |
not | 取反 | 真变假,假变真 |
1age = 202has_ticket = True34can_enter = age >= 18 and has_ticket5needs_help = not has_ticket67print(can_enter) # True8print(needs_help) # False
and 和 or 不一定返回 True 或 False。它们会短路求值,并返回参与判断的某个操作数:
1name = ""2display_name = name or "匿名用户"34print(display_name) # 匿名用户
这段代码中,name 是空字符串,在真值判断中为假,因此 or 返回右边的 "匿名用户"。
and 适合表达“前一个条件成立后,才继续检查后一个条件”:
1user = None23if user is not None and user.get("name"):4print(user["name"])
当 user is not None 为假时,Python 不会继续执行 user.get("name"),因此不会因为对 None 调用方法而报错。
条件过多时,建议拆成多个有意义的变量,不要把一整段业务逻辑压缩成一行:
1is_adult = age >= 182has_valid_ticket = has_ticket34if is_adult and has_valid_ticket:5print("允许进入")
5. 赋值运算符
最基本的赋值运算符是 =。它不是数学里的“相等”,而是把右边表达式的结果绑定给左边的变量。
Python 还提供了复合赋值运算符,把计算和重新赋值合在一起:
| 运算符 | 等价写法 | 示例 |
|---|---|---|
+= | value = value + 1 | value += 1 |
-= | value = value - 1 | value -= 1 |
*= | value = value * 2 | value *= 2 |
/= | value = value / 2 | value /= 2 |
//= | value = value // 2 | value //= 2 |
%= | value = value % 2 | value %= 2 |
**= | value = value ** 2 | value **= 2 |
1count = 123count += 24print(count) # 356count *= 47print(count) # 12
复合赋值只是更短的写法,仍然要注意对象是否可变。对数字使用 += 会让变量指向新的数字对象;对列表使用 += 通常会修改列表内容:
1topics = ["变量"]2topics += ["运算符"]34print(topics) # ['变量', '运算符']
Python 还支持链式赋值和解包赋值:
1first, second = 1, 22first, second = second, first34print(first) # 25print(second) # 1
6. 成员运算符
成员运算符判断一个值是否包含在字符串、列表、元组、集合或字典中:
| 运算符 | 含义 |
|---|---|
in | 包含某个成员 |
not in | 不包含某个成员 |
1topics = ["变量", "运算符", "JSON"]23print("运算符" in topics) # True4print("模块" not in topics) # True5print("Python" in "Python 3.12") # True
对字典使用 in 时,检查的是键,不是值:
1profile = {2"name": "小微",3"age": 18,4}56print("name" in profile) # True7print("小微" in profile) # False
如果需要检查字典的值,可以使用 profile.values();如果需要同时检查键和值,可以使用 profile.items():
1profile = {"name": "小微", "age": 18}23print("小微" in profile.values())4print(("name", "小微") in profile.items())
7. 身份运算符
身份运算符是 is 和 is not,用于判断两个名字是否指向同一个对象:
1first = ["Python"]2second = ["Python"]3third = first45print(first == second) # True,内容相等6print(first is second) # False,不是同一个对象7print(first is third) # True,是同一个对象
普通数据比较值时使用 ==,不要用 is 代替。is 最常见、最明确的场景是判断 None:
1result = None23if result is None:4print("没有查询结果")
8. 位运算符
位运算符直接操作整数的二进制位。业务代码中不一定天天用到,但在权限标记、底层协议和性能敏感的场景中很有用:
| 运算符 | 含义 | 示例 |
|---|---|---|
& | 按位与 | 5 & 3 |
| | 按位或 | 5 | 3 |
^ | 按位异或 | 5 ^ 3 |
~ | 按位取反 | ~5 |
<< | 左移 | 5 << 1 |
>> | 右移 | 5 >> 1 |
1read = 1 # 0012write = 2 # 0103permission = read | write45print(permission) # 3,0116print(permission & read) # 1,拥有读取权限
初学阶段只需要知道位运算处理的是整数的二进制表示。遇到权限标记这类场景时,再结合具体业务学习每一位代表什么。
由于日常开发中,位运算符的使用场景较少,所以这里不展开介绍
9. 运算符优先级
同一个表达式里出现多个运算符时,Python 会按照优先级决定计算顺序。常见的顺序可以先记住下面这几层:
- 括号
(); - 乘方
**; - 正负号
+x、-x; - 乘、除、整除、取余
*、/、//、%; - 加减
+、-; - 比较运算符
==、>、in、is; not;and;or。
1result = 2 + 3 * 42with_parentheses = (2 + 3) * 434print(result) # 145print(with_parentheses) # 20
不要依赖自己记住所有优先级。只要表达式稍微复杂,就主动使用括号:
1is_available = (stock > 0) and (is_enabled or is_admin)
括号不仅能改变计算顺序,也能把作者的意图直接写出来,减少读者和自己之后理解代码的成本。