美文网首页
装饰器的理解

装饰器的理解

作者: BigBigTang | 来源:发表于2019-03-06 22:47 被阅读0次

装饰器:
1.用于装饰其他函数
2.增强被装饰函数的功能
装饰器需要接受一个函数对象作为参数,以对其进行增强

def deco(func):
    def wrapper():
        print "decorate something"
        func()
        print "decorate finish"
    return wrapper
@deco
def test_func():
    return "test func"
test_func()

output:
decorate something
test func
decorate finish

test_func()被装饰之后,运行函数test_func(),会运行装饰器这个函数

当你在用某个@decorator来修饰某个函数func时,如下所示:

@decorator
def func():
    pass

其解释器会解释成下面这样的语句:

func = decorator(func)

先看一个简单的装饰器如下:

def hello(fn):
    def wrapper():
        print "hello, %s" % fn.__name__
        fn()
        print "goodby, %s" % fn.__name__
    return wrapper

@hello
def foo():
    print "i am foo"
  
foo()

输出:

hello, foo
i am foo
goodby, foo

对于一个装饰器的定义:

@hello
def foo():
    print "i am foo"

实际上可以理解成foo = hello(foo),将被包装的函数(foo)当作参数传入装饰器(hello)中,通过一系列包装后将包装后的函数再返回给被包装的函数(foo),实际上就是返回了一个新函数,只不过是根据原函数改造而来并且名字不变。

def out_func(**kwds):
    def real_decorator(fn):
        arg = kwds['arg1'] + kwds['arg2']
        def wapper():
            fn()
            return kwds['arg1'] + kwds['arg2'] + arg
        return wapper
    return real_decorator

@out_func(arg1='11111', arg2='22222')
def hello_world():
    print('hello world')

print(hello_world())

分析:我的理解是装饰器有两层,内层wapper用于包装,外层decorator(real_decorator)用于接收被包装的函数(hello_world)作为参数,并将包装后的函数(wapper)返回给外部。此处的例子有三层,外层还有一个out_func函数的用处是给内层传递参数,由于外部多了一层函数所以装饰器函数(real_decorator)将装饰器本身返回给out_func,于是@out_func就相当于装饰器。

functools.wraps

我们在使用 Decorator 的过程中,难免会损失一些原本的功能信息。

def logged(func):
    def with_logging(*args, **kwargs):
        print func.__name__ + " was called"
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

def f(x):
    """does some math"""
    return x + x * x
f = logged(f)

In [24]: f.__name__
Out[24]: with_logging

由于返回的是包装后的with_logging,所以name等基本信息变成了返回的新函数

而functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 modulenamedoc,或者通过参数选择。代码如下:

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__ + " was called"
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

print f.__name__  # prints 'f'
print f.__doc__   # prints 'does some math'

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__ + " was called"
        return func(*args, **kwargs)
    return with_logging
 
@logged
def f(x):
   """does some math"""
   return x + x * x
 
print f.__name__  # prints 'f'
print f.__doc__   # prints 'does some math'

相关文章

  • Python中的Decorator装饰器

    Decorator 装饰器 理解decorator(装饰器)的关键, 在于理解在python中函数是第一公民, 并...

  • 装饰器详解

    装饰器基本写法: 高级一点的装饰器 带参数的装饰器和类装饰器属于进阶的内容。在理解这些装饰器之前,最好对函数的闭包...

  • [JS函数] 方法 this

    函数 方法 新的东西: 多多理解一下this。 apply和装饰器好理解,apply用于指定this的指向,装饰器...

  • 装饰器的理解

    装饰器:1.用于装饰其他函数2.增强被装饰函数的功能装饰器需要接受一个函数对象作为参数,以对其进行增强 test_...

  • Python装饰器小谈

    近几日再次研究Python装饰器,对装饰器又有了新的理解和应用。如果这篇文章叫做小谈装饰器,不如重谈装饰器更来得亲...

  • 2019-05-26python装饰器到底是什么?

    装饰器例子 参考语法 装饰器是什么?个人理解,装饰器,是python中一种写法的定义。他仍然符合python的基本...

  • python 装饰器 补充

    重新理解python 装饰器 python 装饰器是一个函数,被装饰器所装饰的代码块最终也是一个函数这个对于一般的...

  • Python装饰器

    1. 什么是装饰器? 装饰器是一个用来装饰函数的函数。感觉有点拗口,那么,在我的理解,装饰器只是个辅助函数,有没有...

  • 装饰器

    装饰器比较难理解,而我想的是记住其用法 一、函数装饰器 1、不带参数的函数装饰器,可以直接这样写: def dec...

  • Python - 学习理解带参数的装饰器

    理解带参数的装饰器 参考文章 Python精进-装饰器与函数对象 加了装饰器这段代码从一个函数定义(不会执行任何东...

网友评论

      本文标题:装饰器的理解

      本文链接:https://www.haomeiwen.com/subject/ocmfpqtx.html