重复尝试和除外条款

cru*_*tis 11 python try-catch except

我已经创建了一堆函数,除了所有这些函数之外我需要非常相似,但我讨厌有这么多的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
Run Code Online (Sandbox Code Playgroud)

"try"之后的代码对于函数是不同的,但是"except"之后的代码是相同的.我想整合除语句之外的那些,这样它们就不会让我的代码看起来如此狭窄.有没有办法做到这一点?

Fin*_*las 22

Python装饰器就是你想要的.

你说除了块总是一样的.制作一个可以满足您需求的自定义装饰器.你必须将它应用于每个函数/方法,但它肯定会保存重复.

def handleError(function):
    def handleProblems():
        try:
            function()
        except Exception:
            print "Oh noes"
    return handleProblems


@handleError
def example():
   raise Exception("Boom!")
Run Code Online (Sandbox Code Playgroud)

在应用装饰器的情况下调用方法时:

>>> 
>>> example()
Oh noes
>>> 

您将需要更改异常类型以及您所做的事情,但是您可以获得我要去的地方.

  • 这不是一个很好的例子,因为装饰器不适用于带参数的函数. (2认同)

ire*_*ses 6

try块内的内容是有趣的东西,因此应该在函数中.然后只需选择您想要的功能,并调用它,包含异常.您甚至可以将异常代码编写为函数,并将所选函数作为参数传递给它.例如

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)
Run Code Online (Sandbox Code Playgroud)


use*_*349 5

上面的答案不适用于带参数的函数 - 对于后一种情况,我认为你会想要这样的东西:

def handleError(f):
    def handleProblems(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception:
            print "Oh noes"
    return handleProblems
Run Code Online (Sandbox Code Playgroud)

我们可以像这样测试它:

@handleError
def addTwo(x, y): 
    print(x + y) 

>>> addTwo(5,5)
10
>>> addTwo(5, 's')
Oh noes 
Run Code Online (Sandbox Code Playgroud)