繁体   English   中英

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

[英]Python decorator - Trying to understand a simple example

我试图了解python装饰器。 我设计了一个简单的示例,在该示例中,我希望装饰器函数是一个自定义日志,如果例如我尝试sum_和int以及str ,则只会显示错误

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

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

当我定义函数时,这已经很简单地返回"error" 我怀疑我所做的事情有很多错误...我试图研究有关该主题的其他问题,但是我发现所有这些问题都使我理解如何起草这样一个简单的示例,特别是如何传递参数从原始功能开始。

感谢所有帮助和指导

那是因为您没有将args从函数转发到装饰器,并且catch-all异常捕获 argsNameError 始终指定异常类的原因之一。

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

def log(fun):
    def wrapper(*args):
          print('in decorator!')
          return fun(*args)
    return wrapper

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

print sum_(1,2)

出现错误的原因仅仅是因为装饰器中的args未定义。 关于装饰器,这没什么特别的,只是一个常规的NameError 因此,您可能希望将exception子句限制为TypeError ,这样就不会使其他错误沉默。 完整的实现将是

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装饰器装饰内部函数也是个好主意,该函数将名称和文档字符串从原始函数传送到装饰的函数。

在这种情况下, 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')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM