我刚刚写了一大堆代码,这些代码让我觉得它比最优化更嵌套。我想了解如何改进这种风格的建议,尤其是它更符合“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, (), ())
答案 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)
嗯,这里的诀窍是弄清楚它们是否坏了。这是例外处理 的 处理 部分。我的意思是,至少打印一个警告,说明评论的假设。在实际操作之前担心过度嵌套似乎让你领先于自己。担心在时尚之前做对。