代码之家  ›  专栏  ›  技术社区  ›  Paul McMillan

清理嵌套的Try/Excepts

  •  4
  • Paul McMillan  · 技术社区  · 17 年前

    我刚刚写了一段代码,这段代码给我的印象是嵌套远远超过了最佳嵌套。我想听听关于如何改进这种样式的建议,特别是让它更符合“扁平优于嵌套”

    for app in apps:
        if app.split('.', 1)[0] == 'zc': #only look for cron in zc apps
            try:
                a = app + '.cron'
                __import__(a)
                m = sys.modules[a]
    
                try:
                    min = m.cron_minute()
                    for job in min:
                        k.add_interval_task(job[0], 'minute task', r(M_LB, M_UB),
                                            60*job[1], 
                                            kronos.method.threaded, (), ())
                except AttributeError: #no minute tasks
                    pass
    
                try:
                    hour = m.cron_hour()
                    for job in hour:
                        k.add_daytime_task(job[0], 'day task', range(1, 8), None,
                                           (job[1], r(H_LB, H_UB)), 
                                           kronos.method.threaded, (), ())
                except AttributeError: #no hour tasks
                    pass
    
            except ImportError: #no cron jobs for this module
                pass
    

    编辑:

    for app in apps:
        if app.split('.', 1)[0] != 'zc': #only look for cron in zc apps
            continue
    
        try:
            a = app + '.cron'
            __import__(a)
        except ImportError: #no cron jobs for this module, continue to next one
            continue
    
        m = sys.modules[a]
        if hasattr(m, 'cron_minute'):
            min = m.cron_minute()
            for job in min:
                k.add_interval_task(job[0], 'minute task', r(M_LB, M_UB),
                                    60*job[1], 
                                    kronos.method.threaded, (), ())
    
        if hasattr(m, 'cron_hour'):
            hour = m.cron_hour()
            for job in hour:
                k.add_daytime_task(job[0], 'day task', range(1, 8), None,
                                   (job[1], r(H_LB, H_UB)), 
                                   kronos.method.threaded, (), ())
    
    4 回复  |  直到 17 年前
        1
  •  8
  •   Alex Martelli    17 年前

    因此,我建议:

    for app in apps:
        if app.split('.', 1)[0] != 'zc': #only look for cron in zc apps
            continue
    
        try:
            a = app + '.cron'
            __import__(a)
        except ImportError: #no cron jobs for this module
            continue
    
        # etc etc
    

    另一方面,我还以另一种方式(不依赖于任何尝试/例外)应用了“flat优于nested”,即“如果我在循环的这一段上没有更多的事情要做,继续[即,移动到循环的下一段],而不是“if I have to do:”,然后是大量的嵌套代码。我一直喜欢这种风格(用于if/continue或if/return)以提供以下功能的语言嵌套if's continue (基本上都是现代的,因为C有;-)。

    尽量小 ! 最糟糕的情况是,当您不能简单地在except子句中继续或返回时,您可以使用try/except/else:只在try子句中输入绝对必须存在的内容——可能出现并预期会出现的一小段代码——并在else子句中输入以下代码的其余部分(不应该也不希望出现的部分)。这不会改变嵌套,但会在降低意外隐藏意外异常的风险方面起到巨大的作用!

        2
  •  1
  •   SingleNegationElimination    17 年前

    我想知道,如果每一个单位的工作真的被打破了,他们会不会引起一个态度错误,或者其他一些例外?特别是,如果一份工作真的出了什么问题,你很可能会发现它们。

    另一个有帮助的选项是使用try-catch仅包装有问题的代码,将异常处理程序尽可能地放在异常附近。这里有一个刺:

    for app in apps:
        if app.split('.', 1)[0] == 'zc': #only look for cron in zc apps
            try:
                a = app + '.cron'
                __import__(a)
                m = sys.modules[a]
            except ImportError: #no cron jobs for this module
                                #exception is silently ignored
                                #since no jobs is not an error
                continue
            if hasattr(m, "cron_minute"):
                min = m.cron_minute()
                for job in min:
                    k.add_interval_task(job[0], 'minute task', r(M_LB, M_UB),
                                        60*job[1], 
                                        kronos.method.threaded, (), ())
    
            if hasattr(m, "cron_hour"):
                hour = m.cron_hour()
                for job in hour:
                    k.add_daytime_task(job[0], 'day task', range(1, 8), None,
                                       (job[1], r(H_LB, H_UB)), 
                                       kronos.method.threaded, (), ())
    

    请注意,这里只有一个异常处理程序,我们通过正确忽略它来处理它。 因为我们可以预测不存在一个或另一个属性的可能性,所以我们 明确地检查它,这有助于使代码更加清晰。否则就不是了 很明显,为什么你会发现AttributeError,或者是什么引起了它。

        3
  •  0
  •   Michael Aaron Safyan    17 年前

    您可以创建一个执行主逻辑的函数,以及另一个调用该函数的函数,并用try…except语句包装它。然后,在主应用程序中,您可以只调用那些已经处理异常的函数。(根据《清洁守则》一书的建议)。

        4
  •  0
  •   Hameltime    17 年前

    这里的诀窍是弄清楚它们是否坏了。这就是问题所在 处理 部分 例外 处理 . 我的意思是,至少打印一条警告,说明评论的假设。在实际操作之前担心过多的嵌套似乎是在超越自己。在时尚之前先担心自己是否正确。