找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5252

积分

0

好友

695

主题
发表于 前天 19:31 | 查看: 22| 回复: 0

if else 一层套一层,代码看着没报错,人先看烦了。

这种代码我平时一进项目就能闻出来。不是功能写不出来,是分支一多,判断散了,后面谁改谁心虚。尤其 Python,本来语法就轻,结果被写成了流程图,确实有点亏。

下面这 10 个写法,不是拿来秀技巧的,都是我平时真会拿来替换 if else 的。你不一定一次全用上,但哪怕先换掉两三个,代码味道都会顺不少。

1. 能用映射表,就别一路问下去

很多人写状态分发,第一反应就是 if elif elif。

def send_notice(channel, content):
    if channel == "sms":
        return f"短信发送: {content}"
    elif channel == "email":
        return f"邮件发送: {content}"
    elif channel == "push":
        return f"站内推送: {content}"
    else:
        raise ValueError(f"未知渠道: {channel}")

这类代码一旦渠道变多,就开始发散。直接收成表:

def _send_sms(content):
    return f"短信发送: {content}"

def _send_email(content):
    return f"邮件发送: {content}"

def _send_push(content):
    return f"站内推送: {content}"

SENDERS = {
    "sms": _send_sms,
    "email": _send_email,
    "push": _send_push,
}

def send_notice(channel, content):
    handler = SENDERS.get(channel)
    if not handler:
        raise ValueError(f"未知渠道: {channel}")
    return handler(content)

后面加渠道,不动主流程,这种代码维护起来明显轻松。

2. 提前返回,别把正常逻辑缩进到地板下面

我看代码时,最烦的不是 if 多,是主逻辑被包了四层。

def create_user(payload):
    if payload:
        if payload.get("mobile"):
            if len(payload["mobile"]) == 11:
                return {"ok": True, "mobile": payload["mobile"]}
    return {"ok": False}

这种先把异常路口打掉:

def create_user(payload):
    if not payload:
        return {"ok": False, "reason": "空参数"}

    mobile = payload.get("mobile")
    if not mobile:
        return {"ok": False, "reason": "手机号缺失"}

    if len(mobile) != 11 or not mobile.isdigit():
        return {"ok": False, "reason": "手机号格式不对"}

    return {"ok": True, "mobile": mobile}

主路径更直。排查线上问题时,这种写法日志也更好补。

3. 三元表达式,处理一眼能看懂的小判断

别滥用,但也别不用。

status_text = "已支付" if paid else "待支付"

这种就很好。可你要是写成三层嵌套:

status_text = "已完成" if done else "处理中" if running else "失败"

我一般不太信。不是不能跑,是两周后你自己都得眯着眼看。三元表达式只适合短、平、单分支。

4. 用 dict.get() 兜底,少写一截存在性判断

这招太常见,但很多人还是喜欢先 if key in data

def build_export_row(record):
    return {
        "name": record.get("name", ""),
        "mobile": record.get("mobile", ""),
        "age": record.get("age", 0),
        "city": record.get("city", "未知"),
    }

尤其做导入导出、字段清洗,这种写法很顺。别一边判断 key 存不存在,一边再取值,代码平白长一倍。

5. set 处理多值判断,比连写 or 干净

这个我在权限校验、状态过滤里用得很多。

def can_retry(status):
    if status in {"FAILED", "TIMEOUT", "CANCELLED"}:
        return True
    return False

替换掉这种:

def can_retry(status):
    if status == "FAILED" or status == "TIMEOUT" or status == "CANCELLED":
        return True
    return False

后者没技术含量,就是笨。状态再多一点,自己都不想看。

6. all() / any() 收掉连续条件

表单校验很容易写成 if 地毯。

def valid_order(data):
    return all([
        data.get("user_id"),
        data.get("sku_id"),
        data.get("amount") is not None,
        data.get("amount", 0) > 0,
    ])

或者查风控条件时:

def hit_risk_rule(tags):
    return any([
        "fake_device" in tags,
        "proxy_ip" in tags,
        "black_uid" in tags,
    ])

这种比一串 andor 更聚焦。条件一眼能扫完。

7. match-case 该上就上,别死守 if elif

Python 3.10 之后,这个在命令分发、消息类型处理上很好用。

def parse_event(event):
    match event.get("type"):
        case "pay":
            return f"处理支付单:{event.get('order_id')}"
        case "refund":
            return f"处理退款单:{event.get('order_id')}"
        case "close":
            return f"关闭订单:{event.get('order_id')}"
        case _:
            return f"忽略事件:{event.get('type')}"

这种多分支、同一维度判断的场景,match-case 比 if elif 更像回事。 但也别见到分支就上,条件不在一个维度上,硬写反而更拧巴。

8. 多态或者 策略类,专治“功能越加越长”

这招适合业务稍微复杂一点的时候。比如优惠计算。

class Coupon:
    def calc(self, amount):
        raise NotImplementedError

class FullCutCoupon(Coupon):
    def calc(self, amount):
        return amount - 30 if amount >= 200 else amount

class DiscountCoupon(Coupon):
    def calc(self, amount):
        return round(amount * 0.9, 2)

class NoCoupon(Coupon):
    def calc(self, amount):
        return amount

def settle_amount(amount, coupon: Coupon):
    return coupon.calc(amount)

你当然也能写成:

if coupon_type == "full_cut":
    ...
elif coupon_type == "discount":
    ...

开始就两种券时,没人觉得有问题。到第五种、第八种的时候,味道就出来了。

9. 用异常处理中断错误分支,别拿返回值硬撑

很多脚本喜欢这么写:

def load_price(row):
    if "price" in row:
        if str(row["price"]).isdigit():
            return int(row["price"])
    return 0

这种静默吞错,后面对账最容易出事。我更喜欢让脏数据尽早暴露:

def load_price(row):
    raw = str(row["price"]).strip()
    if not raw.isdigit():
        raise ValueError(f"非法价格: {raw}")
    return int(raw)

批处理里可以配合日志一起用:

def parse_rows(rows):
    result = []
    for idx, row in enumerate(rows, start=1):
        try:
            result.append(load_price(row))
        except Exception as e:
            print(f"[warn] 第{idx}行跳过: {e}")
    return result

错误就是错误,别装成正常分支混过去。

10. 把判断抽成小函数,别把业务主线写成判断合集

这个最朴素,也最容易被忽略。很多函数难看,不是因为 if else,多半是判断和动作搅一锅了。

def is_new_user(user):
    return user.get("register_days", 999) <= 7

def is_high_value(user):
    return user.get("paid_amount", 0) >= 1000

def should_give_coupon(user):
    return is_new_user(user) and is_high_value(user)

def process_user(user):
    if should_give_coupon(user):
        return {"coupon": 50, "tag": "重点转化"}
    return {"coupon": 0, "tag": "普通用户"}

主流程只保留判断结果,细节下沉。后面规则变了,改小函数,不要每次都去主函数里刨。

我见过不少 Python 代码,表面问题是 if else 太多,实际问题是判断和动作没分开,异常和正常路径混着走,分发逻辑全堆在一处




上一篇:旧安卓手机怎么变身Linux小电脑和智能家居中枢?Termux脚本免root部署指南
下一篇:小红书AI应用开发面试复盘:Multi-Agent、Embedding本质与代码实战
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-5-2 17:23 , Processed in 0.795309 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表