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 · 140 天前 · 3155 次点击
    这是一个创建于 140 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设存在多个判断条件,以下以修改用户信息为例,哪种代码结构会更清晰而且性能会好一点? 以下 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  
       140 天前
    那肯定是第二种啊,起码不用数空格
    WoWTxT
        2
    WoWTxT  
       140 天前
    性能不用考虑,清晰肯定第二种
    Vinceeeent
        3
    Vinceeeent  
       140 天前 via Android
    第一种看着都累啊
    wangtian2020
        4
    wangtian2020  
       140 天前   ❤️ 1
    第二种

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

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

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

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


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

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

    enen 我是直接复制了,应该是 if - else if
    sadfQED2
        39
    sadfQED2  
       139 天前
    @xiubin #27
    sadfQED2
        40
    sadfQED2  
       139 天前
    @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  
       139 天前
    性能不用考虑,清晰肯定第二种
    akira
        42
    akira  
       139 天前
    性能应该也是 第二种
    veike
        43
    veike  
       139 天前 via Android
    @bfdh 不冲突,一次性返回全部需要信息即可,和第二种写法类似
    generated
        44
    generated  
       137 天前
    @night98 当然是有的噻,多的很, 比如 https://pydantic-docs.helpmanual.io/
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3129 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 01:04 · PVG 09:04 · LAX 18:04 · JFK 21:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.