我已经创建了一堆函数,除了所有这些函数之外我需要非常相似,但是我讨厌有这么多行的try和除了子句以及每个函数内部相同的代码。例如:
import sys
import random
def foo():
num=random.random()
try:
if num>0.5: print 'OK'
elif num>0.25: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
def bar():
num=random.random()
try:
if num>0.8: print 'OK'
elif num>0.6: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
“try”之后的代码对于函数是不同的,但“except”之后的代码是相同的。我想整合除语句之外的那些,这样它们就不会让我的代码看起来如此狭窄。有没有办法做到这一点?
答案 0 :(得分:22)
Python Decorators就是你想要的。
你说除了块总是一样的。制作一个可以满足您需求的自定义装饰器。你必须将它应用于每个函数/方法,但它肯定会保存重复。
def handleError(function):
def handleProblems():
try:
function()
except Exception:
print "Oh noes"
return handleProblems
@handleError
def example():
raise Exception("Boom!")
调用应用装饰器的方法时:
>>> >>> example() Oh noes >>>
您需要更改异常类型以及您所做的事情,但是您可以获得我的目标。
答案 1 :(得分:6)
try
块内的内容是有趣的内容,因此应该在函数中。然后只需选择您想要的功能,并调用它,包含异常。您甚至可以将异常代码编写为函数,并将所选函数作为参数传递给它。 e.g。
def foo():
num=random.random()
if num>0.5: print 'OK'
elif num>0.25: raise NameError('Too Small')
else: raise KeyboardInterrupt
def bar():
num=random.random()
if num>0.8: print 'OK'
elif num>0.6: raise NameError('Too Small')
else: raise KeyboardInterrupt
def try_numerics(f):
try:
f()
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
# In your main code...
if (need_to_run_foo):
try_numerics(foo)
elif (need_to_run_bar):
try_numerics(bar)
答案 2 :(得分:5)
上面的答案不适用于带参数的函数 - 对于后一种情况,我认为你会想要这样的东西:
def handleError(f):
def handleProblems(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception:
print "Oh noes"
return handleProblems
我们可以这样测试:
@handleError
def addTwo(x, y):
print(x + y)
>>> addTwo(5,5)
10
>>> addTwo(5, 's')
Oh noes
答案 3 :(得分:2)
如果这些是你的实际功能,那么很容易概括它们。
您可以创建一个通用功能
def general(bottom_num, top_num):
num=random.random()
try:
if num>top_num: print 'OK'
elif num>bottom_num: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
这会使代码不再重复并解决try:except:issue
答案 4 :(得分:0)
我最近遇到了同样的情况,在我的情况下,我有一些自定义异常,我需要进一步记录或提升异常。我已经创建了一个装饰器方法来处理各种类型的异常。
try:
obj.some_method()
except Exception as e:
catch_and_log_exception(e)
def catch_and_log_exception(e):
if isinstance(e, MyConnectionError):
print "Connection error : %s." % e.message
sys.exit(1)
elif isinstance(e, MyConnectionTimeout):
print "Connection to server has been timed out. %s" % e.message
sys.exit(1)
elif isinstance(e, MyException):
message = e.explanation if e.explanation else e.message
log_error_message(str(message))
print "Failed, please check the logs."
sys.exit(1)
else:
raise e
希望这有帮助!!