一、操作数基础:什么是操作数?为什么需要自定义操作数?操作数在Python中的本质
各位好,咱们开始这门课的第一章。说实话,我教了这么多年Python,发现很多人在「操作数」这个概念上栽过跟头。有人觉得它太简单,扫一眼就过了;有人又觉得它太抽象,搞不懂到底是个啥。
其实没那么复杂。你想想看,我们写代码就是在跟数据打交道。而操作数,就是这些数据在运算时的「身份」。今天我就带你把它的底裤扒干净。
1.1 什么是操作数?
先看一个最朴素的例子:
3 + 5
这里的 3 和 5 就是操作数,+ 是运算符。操作数就是运算符作用的对象。说白了,就是「被操作的东西」。
再复杂一点:
result = (a * b) + (c / d)
这里的 a、b、c、d 都是操作数。它们可以是变量、字面量、函数返回值,甚至是另一个表达式的结果。
核心定义:操作数是表达式中参与运算的基本单元。在Python中,一切能被运算符作用的「东西」都是操作数。
1.2 操作数的常见类型
我习惯把操作数分成三类,这样好记:
| 类别 | 示例 | 说明 |
|---|---|---|
| 字面量 | 42, 3.14, "hello" |
直接写在代码里的值 |
| 变量 | x, count, user_name |
指向内存中某个对象的名称 |
| 表达式 | (a + b), func() |
运算结果作为另一个运算的操作数 |
举个例子你就明白了:
# 字面量作为操作数
print(10 + 20) # 10 和 20 都是字面量
# 变量作为操作数
x = 10
y = 20
print(x + y) # x 和 y 是变量
# 表达式作为操作数
print((x + y) * 2) # (x + y) 这个表达式的结果是操作数
1.3 为什么需要自定义操作数?
好,问题来了——Python 自带的那些操作数类型(int、float、str、list……)明明够用,为什么还要自己定义?
我在项目中遇到过这样一个场景:需要处理「带单位的数值」,比如 5米 + 3米。用普通 int 行吗?行,但你得自己记住单位。万一有人传了 5米 + 3千克,程序不会报错,结果却毫无意义。
这就是痛点。内置操作数类型无法表达业务语义。你想想看,如果能让 5米 + 3米 自动返回 8米,而 5米 + 3千克 直接抛出异常,是不是爽多了?
我的经验:什么时候该考虑自定义操作数?当你发现代码里到处都在写「转换函数」「校验逻辑」「单位换算」的时候,就是时候了。把这些逻辑封装到操作数里,代码会干净得多。
1.4 操作数在Python中的本质
这里我要说一个很多教程不会讲透的点。在Python里,一切皆对象。操作数也不例外。
你看这个:
a = 10
b = 20
c = a + b
a 和 b 是操作数,它们本质上是 int 类的实例。+ 运算符本质上调用的是 int.__add__ 方法。所以,操作数的本质就是——实现了特定协议的类的实例。
Python 用了一套「魔术方法」(也叫双下方法)来定义操作数的行为:
| 运算符 | 对应的魔术方法 | 说明 |
|---|---|---|
+ |
__add__ |
加法 |
- |
__sub__ |
减法 |
* |
__mul__ |
乘法 |
/ |
__truediv__ |
除法 |
== |
__eq__ |
相等判断 |
< |
__lt__ |
小于比较 |
所以,自定义操作数说白了就是——自己写一个类,然后实现这些魔术方法。
注意:我曾经见过有人一口气实现了十几个魔术方法,结果代码又臭又长。我的建议是:只实现你真正需要的。比如你的类只需要加法,那就只写 __add__,别贪多。
1.5 一张图看懂本章知识体系
下面这张图把操作数的概念、分类、本质和自定义动机串起来了。我建议你多看两眼,后面几章都会围绕这个框架展开。
1.6 一个简单的自定义操作数示例
光说不练假把式。咱们写一个最简单的自定义操作数——Meter 类,让两个米数能直接相加:
class Meter:
def __init__(self, value):
self.value = value
def __add__(self, other):
if not isinstance(other, Meter):
raise TypeError(f"不能将 Meter 与 {type(other).__name__} 相加")
return Meter(self.value + other.value)
def __repr__(self):
return f"{self.value}米"
# 使用
a = Meter(5)
b = Meter(3)
c = a + b
print(c) # 输出:8米
# 错误用法
try:
d = a + 10 # 抛出 TypeError
except TypeError as e:
print(e) # 输出:不能将 Meter 与 int 相加
看到了吗?只用了 __add__ 一个魔术方法,就实现了「带单位的加法」。而且类型安全——乱加会报错,不会静默产生垃圾数据。
一个小技巧:我习惯在自定义操作数里加上 __repr__ 方法,这样调试的时候直接打印对象就能看到有意义的信息,不用每次都 .value。省心。
1.7 本章小结
咱们捋一下今天的内容:
- 操作数就是运算符作用的对象,可以是字面量、变量或表达式
- 自定义操作数是为了让代码能表达业务语义,同时保证类型安全
- 本质是类的实例,通过实现魔术方法来定义运算行为