清理嵌套的Try / Except

时间:2009-07-13 01:51:59

标签: python

我刚刚写了一大堆代码,这些代码让我觉得它比最优化更嵌套。我想了解如何改进这种风格的建议,尤其是它更符合“Flat比嵌套更好”。

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 个答案:

答案 0 :(得分:8)

主要的问题是你的试用条款过于宽泛,特别是最外层的条款:有了这种习惯,你迟早会遇到一个神秘的错误,因为你的一个尝试/除外意外隐藏了一个意外的异常“从你正在呼唤的其他一些功能中冒泡。

所以我建议,改为:

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 is than nest”(不依赖于任何try / except),“如果我在循环的这一段没有更多的事情要做,继续[即继续前进到循环的下一个循环]而不是“如果我有事情要做:”后跟大量的嵌套代码。我总是喜欢这种样式(if / continue或if / return)嵌套如果是提供continue等功能的语言(基本上都是现代的,因为C有它; - )。

但这是一个简单的“扁平与嵌套”风格偏好,问题的关键是:保持你的试用条款!最糟糕的情况是,当你不能简单地继续或在except子句中返回时,你可以使用try / except / else:在try子句中只放入绝对必须存在的东西 - 可能和预期的一小段代码raise - 并在else子句中放入以下代码的其余部分(不应该也不应该引发的部分)。这不会改变嵌套,但是在降低意外隐藏不期望的异常的风险方面会有很大的不同!

答案 1 :(得分:1)

我想知道,如果每个时间单位的作业实际上都被打破了,它们会引发AttibuteError或其他一些异常吗?特别是,如果某件作品真的被破坏了,你可能不会抓住它们。

另一个可以帮助的选项是使用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,甚至是什么甚至提升它都是显而易见的。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

嗯,这里的诀窍是弄清楚它们是否坏了。这是例外处理 处理 部分。我的意思是,至少打印一个警告,说明评论的假设。在实际操作之前担心过度嵌套似乎让你领先于自己。担心在时尚之前做对。