V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kayseen
V2EX  ›  Python

一个简单低级的代码逻辑问题

  •  
  •   kayseen · 2022 年 1 月 4 日 · 4611 次点击
    这是一个创建于 1469 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设存在多个判断条件,以下以修改用户信息为例,哪种代码结构会更清晰而且性能会好一点? 以下 python 伪代码:

    一:

    if 用户存在:
    	if 密码符合规范:
    		if 手机号符合规范:
    			if 邮箱符合规范:
    				do 修改用户信息
    			else:
    				return 邮箱不符合规范
    		else:
    			return 手机号不符合规范
    	else:
    		return 密码不符合规范
    else:
    	return 用户不存在
    

    二:

    if 用户不存在:
    	return 用户不存在
    if 密码不符合规范:
    	return 密码不符合规范
    if 手机号不符合规范:
    	return 手机号不符合规范
    if 邮箱不符合规范:
    	return 邮箱不符合规范
    do 修改用户信息
    
    44 条回复    2022-01-07 18:58:56 +08:00
    xiao109
        1
    xiao109  
       2022 年 1 月 4 日
    那肯定是第二种啊,起码不用数空格
    WoWTxT
        2
    WoWTxT  
       2022 年 1 月 4 日
    性能不用考虑,清晰肯定第二种
    Vinceeeent
        3
    Vinceeeent  
       2022 年 1 月 4 日 via Android
    第一种看着都累啊
    wangtian2020
        4
    wangtian2020  
       2022 年 1 月 4 日   ❤️ 1
    第二种

    从代码的“面相”来看,第一种长的像“回调地狱”,第二种就长得像 async 方法了( JavaScript )
    xingshu1990
        5
    xingshu1990  
       2022 年 1 月 4 日
    原先在 Python 高级编程里看到过第二种 这种优化:

    Python 下,第二种属于短路原则。

    Python 里的“短路原则”:在条件语句中,如果存在多个条件需要判断时,位置靠前的条件导致整个判断语句为 True ( or 语句)或者为 False ( and 语句),就不再进行后续条件的判断。
    looyer
        6
    looyer  
       2022 年 1 月 4 日
    第二种 另外表单输入判断前置 涉及到数据库查询结果的判断后置 只有表单数据都确认规范了 再去请求数据库做进一步判断
    Jooooooooo
        7
    Jooooooooo  
       2022 年 1 月 4 日
    第二种清晰.
    66beta
        8
    66beta  
       2022 年 1 月 4 日
    第二种是几乎适合所有语言的短路原则
    shyrock
        9
    shyrock  
       2022 年 1 月 4 日
    必须是二啊。
    第一种我是没想出来哪种场景有用。
    xingshu1990
        10
    xingshu1990  
       2022 年 1 月 4 日
    @shyrock 第一种是无任何编程基础的新人学着写的。
    FutherAll
        11
    FutherAll  
       2022 年 1 月 4 日
    提前返回
    ayase252
        12
    ayase252  
       2022 年 1 月 4 日
    无疑是第二种,early return

    第一种可读性太差
    Droi
        13
    Droi  
       2022 年 1 月 4 日
    可以试试设计模式了。不知道职责链模式能不能解决你的这个问题。
    adoal
        14
    adoal  
       2022 年 1 月 4 日
    Monad 了解一下
    EchoDeveloper
        15
    EchoDeveloper  
       2022 年 1 月 4 日
    第二种就是卫语句,显然更好. 把不该出现的情况提前返回.
    ianEros
        16
    ianEros  
       2022 年 1 月 4 日
    Fail-fast
    qiaobeier
        17
    qiaobeier  
       2022 年 1 月 4 日
    肯定第二种啊,连你这种伪代码第二种也是漂亮太多了。
    ccraohng
        18
    ccraohng  
       2022 年 1 月 4 日
    if 密码不符合规范:
    return 密码不符合规范
    if 手机号不符合规范:
    return 手机号不符合规范
    if 邮箱不符合规范:
    return 邮箱不符合规范


    都是校验,先走规则校验
    dengji85
        19
    dengji85  
       2022 年 1 月 4 日
    @Droi 借楼问一下,这种业务判断多少人会真的去用设计模式,用了会不会增加复杂度
    PiersSoCool
        20
    PiersSoCool  
       2022 年 1 月 4 日
    肯定第二种
    night98
        21
    night98  
       2022 年 1 月 4 日
    python 没有类似 hibernate valid 的库么,这种基础校验手写太麻烦了把
    daimubai
        22
    daimubai  
       2022 年 1 月 4 日
    肯定第二,能 return 就 return ,return 意味着 return 掉的代码不需要去管了可以降低“思维逻辑负担”,尽管逻辑不复杂
    veike
        23
    veike  
       2022 年 1 月 4 日 via Android
    第二种,可以查一下"卫语句",就是为了降低 if 嵌套的程序复杂性
    Droi
        24
    Droi  
       2022 年 1 月 4 日
    @dengji85 各人项目不会去用,用了反而增加复杂度
    teem
        25
    teem  
       2022 年 1 月 4 日
    2 防御式编程
    chnhyg
        26
    chnhyg  
       2022 年 1 月 4 日
    以卫语句取代嵌套条件表达式的精髓就是:给某一条分支以特别的重视。如果使用 if-then-else 结构,你对 if 分支和 else 分支的重视是同等的。这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句就不同了,它告诉阅读者:“这种情况不是本函数的核心逻辑所关心的,如果它真发生了,请做一些必要的整理工作,然后退出。”——《重构》
    xiubin
        27
    xiubin  
       2022 年 1 月 4 日
    个人可能会这么写,减少 return case ,做统一收口,后面方便加逻辑,比如 log 或者异常监控:

    let result = 0;
    if 用户不存在:
    result = 用户不存在
    if 密码不符合规范:
    result = 密码不符合规范
    if 手机号不符合规范:
    result = 手机号不符合规范
    if 邮箱不符合规范:
    result = 邮箱不符合规范
    log('check result: {result}')
    return result;
    llsquaer
        28
    llsquaer  
       2022 年 1 月 4 日
    if 用户存在 or 密码符合规范 or 手机号符合规范 or 邮箱符合规范:
    return '你输入的数据中有一些地方是错的.自己检查'
    NowTime
        29
    NowTime  
       2022 年 1 月 4 日   ❤️ 1
    @xiubin 那你这种的话,会不会符合多种条件,但只会返回最后一个提示
    bigxianyu
        30
    bigxianyu  
       2022 年 1 月 4 日
    这两者之间的性能差距几乎可以忽略( 不是主要矛盾 ) ,第二种的可读性好多了,所以肯定选第二个
    zwgf
        31
    zwgf  
       2022 年 1 月 4 日
    性能当然是第一种,但是这点性能,没必要
    还是第二种看着舒服
    msg7086
        32
    msg7086  
       2022 年 1 月 4 日 via Android
    @dengji85 如果库已经有现成的功能的话还是用起来方便。
    比如 Rails 里,写 validation 规则比手写代码方便多了。
    https://guides.rubyonrails.org/active_record_validations.html
    inframe
        33
    inframe  
       2022 年 1 月 4 日
    Django DRF 框架里用 validator 可以对每个字段设置规则进行校验,就不用单独写逻辑
    pcbl
        34
    pcbl  
       2022 年 1 月 4 日
    @xiubin 不直接 return 的话,应该用 elif 吧。这些条件是只要满足一个就退出判断的
    yolee599
        35
    yolee599  
       2022 年 1 月 5 日
    用第二种,有错误及时返回,不要再做其他判断了,做了也没用
    meiyoumingzi6
        36
    meiyoumingzi6  
       2022 年 1 月 5 日 via iPhone
    写第一种怕不是要被同事打死
    bfdh
        37
    bfdh  
       2022 年 1 月 5 日   ❤️ 1
    说个题外话,想起以前去一些单位办事,工作人员的答复
    第一次去:身份证没带,办不了
    第二次去:户口本没带,办不了
    第三次去:证件照没带,办不了
    xiubin
        38
    xiubin  
       2022 年 1 月 5 日
    @NowTime #29
    @pcbl #34

    enen 我是直接复制了,应该是 if - else if
    sadfQED2
        39
    sadfQED2  
       2022 年 1 月 5 日
    @xiubin #27
    sadfQED2
        40
    sadfQED2  
       2022 年 1 月 5 日
    @xiubin #27

    let result = "";
    if 用户不存在:
    result += 用户不存在\n
    if 密码不符合规范:
    result += 密码不符合规范\n
    if 手机号不符合规范:
    result += 手机号不符合规范\n
    if 邮箱不符合规范:
    result += 邮箱不符合规范\n
    log('check result: {result}')
    return result;

    我一般都是这样写,不然多种条件部分和,日志打印不全,排除问题的时候日志反而误导人
    ariera
        41
    ariera  
       2022 年 1 月 5 日
    性能不用考虑,清晰肯定第二种
    akira
        42
    akira  
       2022 年 1 月 5 日
    性能应该也是 第二种
    veike
        43
    veike  
       2022 年 1 月 5 日 via Android
    @bfdh 不冲突,一次性返回全部需要信息即可,和第二种写法类似
    generated
        44
    generated  
       2022 年 1 月 7 日
    @night98 当然是有的噻,多的很, 比如 https://pydantic-docs.helpmanual.io/
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   4037 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 05:25 · PVG 13:25 · LAX 21:25 · JFK 00:25
    ♥ Do have faith in what you're doing.