Python装饰器 - 试图理解一个简单的例子

时间:2017-04-20 14:48:32

标签: python decorator

我想了解python装饰器。 我设计了一个简单的例子,我希望装饰器功能是一个自定义日志,只是打印错误,例如我尝试sum_和int以及str

def log(fun):
    try:
        return fun(*args)
    except:
        print('error!')        

@log
def sum_(a,b):
    return a+b

这在我定义函数时已经很简单地返回"error"。我怀疑我做了多少错误的事情......我试着调查关于那个主题的其他问题,但是我发现它们都很复杂,无法理解如何起草这样一个简单的例子,尤其是如何传递参数从原来的功能。

所有帮助和指示赞赏

3 个答案:

答案 0 :(得分:3)

那是因为你没有将ByteBuffer从函数转发给装饰器,而 catch-all 异常捕获 args NameError;始终指定异常类的原因之一。

以下是代码的修改版本,删除了try-catch并正确转发了函数参数:

args

答案 1 :(得分:2)

您收到错误的原因仅仅是因为装饰器中未定义args。这与装饰器没什么特别之处,只是常规的NameError。因此,您可能希望将异常子句限制为仅TypeError s,这样您就不会消除其他错误。完整的实施将是

import functools

def log(fun):
    @functools.wraps(fun)
    def inner(*args):
        try:
            return fun(*args)
        except TypeError:
            print('error!')
    return inner

@log
def sum_(a, b):
    return a + b

使用functools.wrap装饰器装饰内部函数也是一个好主意,装饰器将原始函数中的名称和文档字符串传递给装饰的函数。

答案 2 :(得分:1)

在这种情况下,log装饰器不返回函数,而是返回值。这可能指向装饰器函数替换原始函数的假设,实际上,它被调用以创建替换函数。

可能代表意图的修正:

def log(fun):
    def my_func(*args):
        try:
            return fun(*args)
        except:
            print('error!')

    return my_func

在这种情况下,my_func是为sum_(1, 2)调用的实际函数,在内部,它调用装饰器接收的原始函数(原始sum_)作为参数

一个简单的例子,说明了行动的顺序:

def my_decorator(fun):
    print 'This will be printed first, during module load'
    def my_wrapper(*args):
        print 'This will be printed during call, before the original func'
        return fun(*args)

    return my_wrapper()

@my_decorator
def func():
    print('This will be printed in the original func')