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
pc10201
V2EX  ›  Python

如果程序中有大量的逻辑判断,写一堆 if else 还是 try catch?有没有更好的办法?

  •  
  •   pc10201 · 2014-03-28 10:15:23 +08:00 · 8552 次点击
    这是一个创建于 3892 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我现在就遇到一个问题,一个小程序,里面有许多判断,一步一步走的
    比如检查用户输入的值,再去数据库去查,再去文件中查等等~~
    如果用户输入正确,没有多大问题的
    但你知道的,不要相信用户,如果只按正常的步骤来,显得程序不够健壮
    但写一大堆if else,再加上python的缩进会不会让代码很难看?
    难道用一大堆ry..catch?会不会有性能问题,代码也不太好看?
    大家是怎么解决异常问题的?还是设计程序时尽量把每一种情况都考虑到?
    24 条回复    1970-01-01 08:00:00 +08:00
    akira
        1
    akira  
       2014-03-28 10:19:25 +08:00
    还是设计程序时尽量把每一种情况都考虑到
    qiayue
        2
    qiayue  
       2014-03-28 10:26:20 +08:00   ❤️ 6
    直线,不要层层嵌套
    if(错误情况1){
    //错误1处理
    return;
    }
    //正常情况1
    ...
    if(错误情况2){
    //错误2处理
    return;
    }
    //正常情况2
    ...
    if(错误情况3){
    //错误3处理
    return;
    }
    //正常情况3
    ...
    最终完成
    roricon
        3
    roricon  
       2014-03-28 10:34:06 +08:00
    你可以把这些输入检查写成函数,缩进看起来会舒爽一些,也方便复用。
    soruNis
        4
    soruNis  
       2014-03-28 10:34:34 +08:00
    how about this:

    interface ICheck{
    boolean check();
    void dealWith();
    }

    ICheck condition_one = new ICheck(){
    boolean check(){...}
    void dealWith(){...}
    };
    ...

    List<ICheck> allConcerns = new LinkedList<>();
    allConcerns.add(condition_one);
    ...

    for(ICheck condition : allConcerns){
    if(condition.check()){
    condition.dealWith();
    }
    }
    soruNis
        5
    soruNis  
       2014-03-28 10:41:46 +08:00
    啊。。。抱歉, 没看清楚, python节点 ... 不过原理应该类似吧。

    虽然是ducktyping, 对类似的逻辑也是有支持的http://docs.python.org/2/library/abc.html
    dcoder
        6
    dcoder  
       2014-03-28 10:52:53 +08:00
    逻辑分支多到一定程度,要上 state machine
    otakustay
        7
    otakustay  
       2014-03-28 10:53:58 +08:00
    作为一个健壮的程序,不写if/else你就算catch了也无法进行精确的日志记录,比如错在哪什么错能不能从错误中恢复,所以if/else省不了
    Monad
        8
    Monad  
       2014-03-28 10:54:21 +08:00 via iPhone
    跑个题 感觉用Haskell的我来处理应该非常简洁方便了
    linuxer
        9
    linuxer  
       2014-03-28 10:59:17 +08:00
    论 if else 的正确用法。
    yakiang
        10
    yakiang  
       2014-03-28 11:05:02 +08:00
    http://sfau.lt/bNbx9B 虽然好像跟lz实际情况不大相符
    raincious
        11
    raincious  
       2014-03-28 11:05:18 +08:00
    @qiayue +1 这是最简单的解决方案。



    相比一层层嵌套,可读性高下立判啊

    http://i.imgur.com/08lBSy0
    9hills
        12
    9hills  
       2014-03-28 11:18:17 +08:00
    以前我也自己判断,后来发现了WTForms
    hitsmaxft
        13
    hitsmaxft  
       2014-03-28 11:23:07 +08:00
    前端js多做限制
    后端根据自动写好模块(比如拆分function), 个个模块各司其职
    那么结果就是

    try:
    result = [checker(x) for checker in checkerlist ]
    catch
    something

    这是自己实现的,

    更完善的就要用 高阶的form library和 model 进行校验
    binux
        14
    binux  
       2014-03-28 11:24:36 +08:00
    check_funcs = [check_username, check_password, check_email, ]
    for each in check_funcs:
    __try:
    ____ret = each(from_data)
    __except Exception, e:
    ____ret = False
    __if ret is not True:
    ____raise Error
    wizaliu
        15
    wizaliu  
       2014-03-28 11:27:27 +08:00
    switch行吗?
    Akagi201
        16
    Akagi201  
       2014-03-28 11:32:34 +08:00 via iPhone
    多态啊,if else不是被批判过吗
    cxe2v
        17
    cxe2v  
       2014-03-28 11:45:46 +08:00
    @Akagi201 楼主要的是判断数据是否为正确的,你怎么用多态?
    senghoo
        18
    senghoo  
       2014-03-28 12:13:00 +08:00
    层层封装。一层一层调用。
    halfelf
        19
    halfelf  
       2014-03-28 12:20:17 +08:00
    如果是OOP,那么这就是典型的代码坏味道,连续对一个值判断if else if在OOP里的正确做法是多态,自动匹配派生类方法
    shyrock
        20
    shyrock  
       2014-03-28 13:31:13 +08:00
    我更喜欢chain of responsibility模式
    wity_lv
        21
    wity_lv  
       2014-03-28 13:37:24 +08:00
    可以使用try catch.
    用CAS做单点登陆的时候,Client端的错误处理使用的是try ... catch ...

    try {

    cas.login(token);

    } catch (UserNotFoundException ex) {
    //...
    } catch (WrongPasswrdException ex) {
    //...
    } catch (AuthFailException ex) {
    //...
    }

    // do success.


    以上的Exception仅供说明用.

    一定要用if else, 参考2楼,快速return的方式中断。
    est
        22
    est  
       2014-03-28 14:05:09 +08:00   ❤️ 1
    看到LZ多个地方问了这个问题。好吧。其实就具体问题来说,对付用户登录这种逻辑判断就一个字——能用+忍!
    konakona
        23
    konakona  
       2014-03-29 01:03:38 +08:00
    如果这些判断是可重复的,完全可以写进函数里。

    function isA(){
    if(){}
    }
    function isB(){
    if(){}
    }
    ....




    //////////////////

    //调用部分

    isA();

    isB();

    逻辑清晰可见。
    davidli
        24
    davidli  
       2014-04-07 20:12:26 +08:00
    前几天刚看了腾讯在网站上控制用户登录的JS代码, 一个简单粗暴的for加if if if if if if if .
    大意是:
    for all form.values
    if name="username": xxx
    if name="pswd" : xxx
    if name="mibao" : xxx
    if name="verifycode" : xxx
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2678 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 12:24 · PVG 20:24 · LAX 04:24 · JFK 07:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.