use*_*903 16 python queue exception-handling
在与某人就Python中的异常处理进行了短暂的辩论 - 由于处理队列对象而引发的 - 我以为我会把它扔出去......
import Queue
q = Queue.Queue()
try:
task=q.get(False)
#Opt 1: Handle task here and call q.task_done()
except Queue.Empty:
#Handle empty queue here
pass
#Opt2: Handle task here and call q.task_done()
Run Code Online (Sandbox Code Playgroud)
import Queue
q = Queue.Queue()
if q.empty():
#Handle empty queue here
else:
task = q.get()
#Handle task here
q.task_done()
Run Code Online (Sandbox Code Playgroud)
一个参数是方法1是错误的,因为队列为空不是错误,因此不应使用Queue.Empty异常处理.此外,如果您认为任务处理部分可能很大,那么在以这种方式编码时,它可能会使调试更加困难.
另一个论点是,在Python中可以接受任何一种方式,并且如果任务处理很大,处理try/except之外的任务可能有助于调试,尽管同意这可能看起来比使用方法2更丑.
意见?
更新:在回答1出现之后再多一点信息......争论是在方法1在一些多线程代码中使用之后开始的.在这种情况下,代码将获取锁(来自threading.Lock对象)并在其返回的任务或Queue.Empty被抛出时释放它
更新2:我们俩都不知道队列对象是线程安全的.看起来像尝试/除了是要走的路!
Ned*_*der 34
方法2是错误的,因为当您可以在一个步骤中完成操作时,您将分两步执行操作.在方法2中,您检查队列是否为空,然后(很快,但仍然更晚),尝试获取该项目.如果你有两个线程从队列中拉出项目怎么办?get()仍然可能因空队列而失败.如果在检查项目为空之后将项目添加到队列中会怎样?这些是一些微小的机会窗口,其中错误蔓延到并发代码.
一步到位,它是迄今为止更好的选择.
import Queue
q = Queue.Queue()
try:
task = q.get(False)
except Queue.Empty:
# Handle empty queue here
pass
else:
# Handle task here and call q.task_done()
Run Code Online (Sandbox Code Playgroud)
不要挂断"异常应该是错误".例外只是另一种沟通渠道,使用它们.在此处使用"else"子句来缩小exception子句的范围.
一个论点是方法 1 是错误的,因为队列为空不是错误,因此不应使用 Queue.Empty 异常处理
异常不一定是“错误”,它是一种通用的流控制机制,并且确实在少数情况下(SysExit、StopIteration 等)使用这种方式。
这里的好问题是:最常见的情况是什么 - 空队列或非空队列。除非你确定知道,否则你想要 AskBeforeYouLeap,因为它很可能更便宜。
| 归档时间: |
|
| 查看次数: |
39917 次 |
| 最近记录: |