有时我需要在for
循环中使用以下模式。有时在同一个循环中不止一次:
try:
var = 'attempt to do something that may fail on a number of levels'
except Exception, e:
log(e)
continue
现在我没有看到在函数中包装它的好方法,因为它不能return continue
:
def attempt(this):
try:
return this
except Exception, e:
log(e)
# 1. continue # <-- syntax error: continue not properly in loop or
# 2. return continue # <-- invalid syntax
# 3.
return False # <-- this sort of works, but makes me feel powerless
如果我return False
,我可以:
var = attempt('to do something that may fail on a number of levels')
if not var:
continue
但我觉得这不是正义。我想从continue
函数中将for循环告诉attempt
(或伪造它)。
答案 0 :(得分:9)
Python已经有了一个非常好的构造来做这件事并且不使用continue
:
for i in range(10):
try:
r = 1.0 / (i % 2)
except Exception, e:
print(e)
else:
print(r)
但是,我不会嵌套这个,或者你的代码很快会变得非常难看。
在你的情况下,我可能会做更多这样的事情,因为对单个函数和flat is better than nested进行单元测试要容易得多:
#!/usr/bin/env python
def something_that_may_raise(i):
return 1.0 / (i % 2)
def handle(e):
print("Exception: " + str(e))
def do_something_with(result):
print("No exception: " + str(result))
def wrap_process(i):
try:
result = something_that_may_raise(i)
except ZeroDivisionError, e:
handle(e)
except OverflowError, e:
handle(e) # Realistically, this will be a different handler...
else:
do_something_with(result)
for i in range(10):
wrap_process(i)
请记住始终catch specific exceptions。如果您不希望抛出特定异常,则继续处理循环可能不安全。
如果你真的不想处理异常,我仍然认为这是个坏主意,那么抓住所有异常(except:
)而不是handle(e)
,只需pass
。此时wrap_process()
将结束,跳过完成实际工作的else:
- 块,然后您将进入for
循环的下一次迭代。
答案 1 :(得分:5)
异常的整个想法是它们跨多个间接层工作,即,如果您的调用层次结构内部有错误(或任何其他异常状态),您仍然可以捕获它在更高的层次上并妥善处理。
在你的情况下,假设你有一个函数attempt()调用函数attempt2()和attempt3()调用层次结构,并且attempt3()可能遇到一个异常状态,它应该导致主循环终止:< / p>
class JustContinueException(Exception):
pass
for i in range(0,99):
try:
var = attempt() # calls attempt2() and attempt3() in turn
except JustContinueException:
continue # we don't need to log anything here
except Exception, e:
log(e)
continue
foo(bar)
def attempt3():
try:
# do something
except Exception, e:
# do something with e, if needed
raise # reraise exception, so we catch it downstream
你甚至可以自己抛出一个虚拟异常,这只会导致循环终止,甚至不会被记录。
def attempt3():
raise JustContinueException()
答案 2 :(得分:3)
也许你想继续?你可以去看看Eric Lippert explains them如何(如果你已经准备好了你的思绪,但在Python中它看起来有点像这样:
def attempt(operation, continuation):
try:
operation()
except:
log('operation failed!')
continuation()
你可以在你的循环中做到:
attempt(attempt_something, lambda: foo(bar)) # attempt_something is a function
答案 3 :(得分:2)
认为您在foo
工作的所有项目上映射attempt
。所以attempt
是一个过滤器,很容易将其写为生成器:
def attempted( items ):
for item in items:
try:
yield attempt( item )
except Exception, e:
log(e)
print [foo(bar) for bar in attempted( items )]
答案 4 :(得分:1)
你可以用这个:
for l in loop:
attempt() and foo(bar)
但你应该确保attempt()返回True或False。
但是,真的,Johnsyweb的回答可能更好。
答案 5 :(得分:1)
我通常不会发布第二个答案,但如果您真的不喜欢my first answer,这是另一种方法。
请记住,函数可以返回tuple
。
#!/usr/bin/env python
def something_that_mail_fail(i):
failed = False
result = None
try:
result = 1.0 / (i % 4)
except:
failed = True # But we don't care
return failed, result
for i in range(20):
failed, result = something_that_mail_fail(i)
if failed:
continue
for rah in ['rah'] * 3:
print(rah)
print(result)
我认为try ... except ... else
是要走的路,但你不应该默默地忽略错误。 警告经纪人以及所有这些。
答案 6 :(得分:1)
除了上下文,我只想简短地回答这个问题。不,函数不能continue
可以调用它。这是因为它没有关于此上下文的信息。此外,它会引发一整类新的问题,比如如果调用该函数而没有周围的循环来处理continue
会发生什么?
但是一个函数可以通过各种方式信号它希望调用者continue
当前执行的任何循环。一种方法当然是返回值。例如,返回False
或None
来表示此信号。另一种发出信号的方式是提出一个特殊的Exception
:
class ContinuePlease(Exception): pass
def f():
raise ContinuePlease()
for i in range(10):
try:
f()
except ContinuePlease:
continue
答案 7 :(得分:0)
import sys if '3.4' in sys.version: from termcolor import coloreddef list_attributes(module_name): '''Import the module before calling this func on it.s ''' for index, method in enumerate(dir(module_name)): try: method = str(method) module = 'email' expression = module + '.' + method print('*' * len(expression), '\n') print( str(index).upper() + '. ',colored( expression.upper(), 'red'), ' ', eval( expression ).dir() , '...' , '\n'2 ) print('' * len(expression), '\n') print( eval( expression + '.doc' ), '\n'*4, 'END OF DESCRIPTION FOR: ' + expression.upper(), '\n'*4) except (AttributeError, NameError): continue else: pass finally: pass
答案 8 :(得分:-4)
编辑:删除了我说的所有愚蠢......
最后的答案是重写整个事情,所以我不需要像那样编码。