“标志”概念的Python方式

时间:2019-06-22 14:45:17

标签: python

请考虑以下情况:

flag = 'a'
while True:
    try:
        # something that might fail
    except:
        # fix failure
        flag = 'b'
    else:
        break

print(flag)

在这种情况下,我觉得必须有一种更好的方法来找出发生的情况而不使用标志,但是无法想到更“ pythonic”的东西。

3 个答案:

答案 0 :(得分:2)

您可以将对异常/默认情况的处理拉入let $sub, $ul = $('<ul/>') $(':header').each(function() { let $this = $(this), $prev = $this.prev(':header'), $parent = $prev.length && $prev.prop('tagName') < $this.prop('tagName') ? $sub : $ul $parent.append('<li><a>' + $this.text() + '</a></li>') $sub = $('<ul/>').appendTo($parent.find('li:last')) }) $('body').html($ul)<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h1>Wow</h1> <h2>Blablablub</h2> <p>Lorem Ipsum...</p> <h1>Lalalala</h1> <p>Lorem Ipsum...</p> <h1>Ble</h1> <h2>Test</h2> <h3>Third</h3> <h3>Third</h3> <p>Lorem Ipsum...</p> <h1>First</h1> <h2>Second</h2> <p>Lorem Ipsum</p> <h3>Third</h3> <h1>First</h1> <h2>Second</h2> <p>Lorem Ipsum</p> <h3>Third</h3>块中。但是,这是不同的代码,因为现在退出except循环后,您将在每个异常上打印而不是仅打印一次,因此对于else / {{1} } / while在循环之外。如果您在循环内,但仍然只希望在循环完成后打印一次(即,一旦未引发异常),我认为您的方法就足够清楚了。

try

答案 1 :(得分:2)

我认为这更多是一个通用的编程问题。使用好名字代表您的意思。 “标志”是什么意思?将其重命名为“完成”并重新阅读代码,您会看到大量不必要的内容,可以进行简单的while循环。

numerator = 1
denominator = 0

done = False
while not done:
    try:
        x = numerator // denominator
        done = True
    except:
        denominator = 1

但是要对发生的事情以及原因有一个很好的了解,我们想添加日志记录(也是常规编程,而不是专门针对pythonic)。例如,这将使您能够跟踪许多不同异常处理程序中的许多不同代码路径。

import logging

# one time setup, can be in a different file
log = logging.getLogger('myapp')
log.setLevel(logging.ERROR)
fh = logging.FileHandler('myapp.log')
log.addHandler(fh)

log.info('about to begin')
done = False
while not done:
    try:
        x = n // d
        done = True
    except NameError as e:
        log.error('oops forgot to initialize: ' + str(e))
        n = 1
        d = 0
    except ZeroDivisionError as e:
        log.error('division by zero')
        d = 1
    except Exception as e:
        log.error('unknown error: ' + str(e))

log.info('done')

错误将存储在您指定的日志文件中。您可以控制是否记录日志以及将日志放置在何处。例如,我有用于开始和结束的log.info消息,但是您并不总是想要所有东西。他们不记录日志,因为我将日志级别设置为ERROR,因此此日志文件“ myapp.log”将仅包含log.error消息。

想想像打印语句一样记录日志,如果您确实想知道它,它只会去您想去的地方,因此您可以有效地将其留在那儿。 logging.DEBUG消息特别适合于在调试程序时知道程序中何时发生了事情,但是稍后通过设置不同的日志记录级别将其禁用。

答案 2 :(得分:1)

我喜欢另一种模式:

  1. 将不安全的函数包装到安全的函数中,该函数将在失败时返回False或None
  2. 设置初始值
  3. 做一个while <failing>

示例:

# It only works for positive numbers
In [24]: def run_safe(x):
    ...:     if x < 0:
    ...:         x = 0
    ...:     try:
    ...:         return 100 / x
    ...:     except Exception:
    ...:         return None


In [25]: i = -4

In [26]: while run_safe(i) is None:
    ...:     print("i={} failed".format(i))
    ...:     i += 1
    ...:
    ...:
i=-4 failed
i=-3 failed
i=-2 failed
i=-1 failed
i=0 failed

# At the end i has the value that succeeds
In [27]: print(i)
1

对我来说,此方法将危险代码(现在位于函数中)与while循环中的“修复”分开。当两个代码(风险代码或修订代码)都很复杂时,我发现它更容易阅读。