Python装饰器

1)     print打印语句耦合太高,输出信息的功能,属于非业务代码。灵活度太差。

print在业务代码中是属于侵入式代码。

2)装饰器

#第一步代码

def add(x,y):

    return x+y

 

def logger(fn):

    print('before')

    ret=fn(4,5)

    print('end')

    return ret

 

print(logger(add))

#第二步多个参数优化

def add(x,y):

    return x+y

 

def add1(x,y,*,z=6):

    return x+y+z

 

def logger(fn,*args,**kwargs):

    print('before')

    ret=fn(*args,**kwargs)

    print('end')

    return ret

a=logger(add1,4,5,z=7)

print(a)

#第三步

def add(x,y):

    return x+y

 

def add1(x,y,*,z=6):

    return x+y+z

 

def logger(fn):

    def _logger(*args,**kwargs):

        print('before')

        ret=fn(*args,**kwargs)   #调用add1

        print('end')

        return ret

    return _logger

add1=logger(add1)     #内层函数_logger

a=add1(4,5,z=7)     #logger(add1,4,5,z=7)

print(a)

#第四步

def add(x,y):

    return x+y

 

def add1(x,y,*,z=6):

    return x+y+z

 

def logger(fn):

    def _logger(*args,**kwargs):

        print('before')

        ret=fn(*args,**kwargs)   #调用add1

        print('end')

        return ret

    return _logger

#add1=logger(add1)     #内层函数_logger

a=logger(add1)(4,5,z=7)     #logger(add1,4,5,z=7)

print(a)

#第五步

def add(x,y):

    return x+y

 

def logger(fn):

    def _logger(*args,**kwargs):

        print('before')

        ret=fn(*args,**kwargs)   #调用add1

        print('end')

        return ret

    return _logger

 

@logger

def add1(x,y,*,z=6):   #add1 = logger(add1)

    return x+y+z

 

#add1=logger(add1)     #内层函数_logger

a=add1(4,5,z=7)     #logger(add1,4,5,z=7)

print(a)

#第六步包装函数wrapper

def logger(fn):
    def wrapper(*args,**kwargs):
        print('before')
        ret = fn(*args,**kwargs)
        print('end')
        return ret
    return wrapper
@logger
def add(x,y,*,z=6):
    return x+y+z
@logger
def add1(x,y):   #add=logger(add)
    return x+y

#b=logger(add)
a=add(4,5,z=10)
print(a)

 

 

 

 

 

 

 

3)@logger的语法格式。

装饰器(无参)

他是一个函数,函数作为他的形参。

返回的值也是一个函数。

可以使用@function调用。

Wrapper表示被包装函数。

Wrapperd表示包装函数。

4)装饰器和高阶函数。

装饰器是高阶函数,但是装饰器是对传入的函数的功能进行装饰,功能增强。

#装饰器

增强函数,而不是非侵入式函数。把函数名作为其参数。

装饰器:Python中的装饰器是一种语法糖,是一个函数,使用的函数作为参数传入。功能往往写成高阶或者嵌套函数,为了不侵入元函数。增强其功能。分为带参与无参的装饰器。

 

import datetime

import time

 

def logger(fn):

    def wrapper(*args,**kwargs):

        print("args={},kwargs={}".format(args,kwargs))

        start = datetime.datetime.now()

        ret = fn(*args,**kwargs)

        duration = datetime.datetime.now() - start

        print("function{}took{}s.".format(fn.__name__,duration.total_seconds()))

        return ret

    return wrapper

@logger  #add = logger(add)

def add(x,y):

    print("===call add =======")

    time.sleep(2)

    return x+y

 

print(add(4,y=1))

 

装饰器:装饰器函数,前置功能增强,被增强函数,后置功能增强。

#import datetime
import time

def logger(fn):
    def wrapper(*args,**kwargs):
        print("{}{}".format(args,kwargs))
        start = datetime.datetime.now()
        n = fn(*args,**kwargs)
        duration=datetime.datetime.now() - start
        print("function{}took{}s".format(fn.__name__,duration.total_seconds()))
        return n
    return wrapper

@logger
def add(x,y):
    print("====call add =======")
    time.sleep(2)
    return x+y

b=add(3,y=4)
print(b)
装饰器的作用

1)装饰器是AOP面向切面编程的思想体现。

面向对象往往需要通过继承或者组合依赖等方式调用一些功能,这些功能的代码往往可能在多个类中出现。比如logger,这样造成代码的重复,增加了耦合,logger改变影响所有使用他的类或者方法。

而AOP在需要的类或方法上切下,前后的切入点可以加入增强的功能,比如logger函数功能就是对 业务函数增加日志,而业务函数中应该把业务函数无关的日志功能剥离干净。

2)装饰器的应用场景:

日志、监控、权限、设计、参数检查、路由等处理:

这些功能与业务功能无关,很多业务都需要公共功能,所以适合独立出来,需要的时候,对目标对象增强。

 

posted @ 2018-11-12 16:42  Python爱好者666  阅读(119)  评论(0)    收藏  举报