推荐学习书目
› 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 · Jan 4, 2022 · 5471 views
    This topic created in 1767 days ago, the information mentioned may be changed or developed.

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

    一:

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

    二:

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

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

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

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

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


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

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

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

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

    我一般都是这样写,不然多种条件部分和,日志打印不全,排除问题的时候日志反而误导人
    ariera
    ariera
    Jan 5, 2022
    41
    性能不用考虑,清晰肯定第二种
    akira
    akira
    Jan 5, 2022
    42
    性能应该也是 第二种
    veike
    veike
    Jan 5, 2022 via Android
    43
    @bfdh 不冲突,一次性返回全部需要信息即可,和第二种写法类似
    generated
    generated
    Jan 7, 2022
    44
    @night98 当然是有的噻,多的很, 比如 https://pydantic-docs.helpmanual.io/
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2039 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 95ms · UTC 02:29 · PVG 10:29 · LAX 18:29 · JFK 21:29
    ♥ Do have faith in what you're doing.