库存清洗脚本里看到这么一段,我第一眼就想删。
tmp = sku_asku_a = sku_bsku_b = tmp
不是它错了,是太像从 C 语言课本里搬过来的。Python 里交换两个变量,正常就写一行:
sku_a, sku_b = sku_b, sku_a
这事小,但我见过不少代码就是从这种小地方开始别扭的。一个批处理脚本,本来三十行能看完,硬是写出一堆临时变量,后面再夹几个状态字段,读代码的人就开始猜:这个 tmp 后面还会不会用?有没有被覆盖?是不是有业务含义?
没有。它只是个中间变量。
Python 交换变量靠的是“右边先算完,左边再接住”。
看这个例子:
left_box = "A1001"right_box = "B7782"left_box, right_box = right_box, left_boxprint(left_box) # B7782print(right_box) # A1001
执行到交换这一行时,Python 会先把右边的 right_box, left_box 取出来,形成一组值,然后再按位置塞回左边。
所以它不会出现这种问题:
left_box = right_boxright_box = left_box
这两行看着也像交换,其实已经把 left_box 原来的值弄丢了。
现场排这种问题挺烦的,日志里通常长这样:
before swap: left=A1001 right=B7782after swap: left=B7782 right=B7782
看到两个值一样,我一般先不怀疑数据源,先搜有没有这种“手写交换”。因为这种 bug 没报错,跑得还挺安静。
我平时写批量处理脚本,经常在调整顺序时用这个写法。
比如导入一批区间配置,有人把开始时间和结束时间填反了。你不能直接让任务挂掉,有些数据可以兜一下:
deffix_time_range(row): start_at = row["start_at"] end_at = row["end_at"]if start_at > end_at: start_at, end_at = end_at, start_at row["remark"] = "time_range_fixed" row["start_at"] = start_at row["end_at"] = end_atreturn row
这里如果写成 tmp 也不是不行,但没必要。交换动作本身就很清楚,代码读到这里,不会多想。
再看一个更像脚本里的场景。处理接口返回的价格区间,低价高价可能被上游传反:
defnormalize_price(item): low = int(item.get("low_price") or0) high = int(item.get("high_price") or0)if low and high and low > high: low, high = high, lowreturn {"sku": item["sku"],"low_price": low,"high_price": high, }
这种代码我愿意留下。判断条件、交换动作、返回结果都贴在一起,没什么绕的。
有些人会问,既然不用中间变量,那能不能用异或交换?
a = a ^ bb = a ^ ba = a ^ b
这东西我基本不写。它只适合整数,还怕两个变量指向同一个值的特殊情况,更要命的是可读性差。你把它放到业务代码里,后面接手的人大概率要停下来想几秒。
代码让人停下来,不一定是高级,有时只是添堵。
Python 里更要注意一点:左边变量数量和右边值数量要对上。
a, b = 10, 20a, b = b, a # 正常x, y = 1, 2, 3# 直接 ValueError
报错会很直接:
ValueError: too many values to unpack
还有一种写法在列表里也常用,比如交换两个位置的数据:
orders = ["paid", "packed", "checked"]orders[1], orders[2] = orders[2], orders[1]print(orders)# ['paid', 'checked', 'packed']
这个比先 pop 再 insert 干净多了。尤其是做排序、修正顺序、调整字段位置时,一行交换就够。
我自己判断要不要这么写,一般就看两点。
第一,交换是不是纯交换。如果交换中间还夹着校验、转换、日志,那就拆开写,别硬挤一行。
第二,变量名是不是清楚。像 a, b = b, a 在小例子里没问题,业务代码里最好别全是 a、b。你写成 min_price, max_price = max_price, min_price,别人一眼知道你在修价格边界。
所以这不是语法炫技。
在 Python 里,不使用中间变量交换两个变量,就写:
x, y = y, x
该用就用,别再手写 tmp。除非你真想让后面的人多看三行。