6月4日 python学习总结 装饰器复习

1.  装饰器的原理以及为什么要使用装饰器

在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

在不影响原代码结构的情况下为其添加功能

2.  装饰器的基本用法  

def test(func):
    def warpper(*args,**kwargs):
        print("====start====")
        func(*args,**kwargs)
        print("=====end====")
    return warpper

@test
def f():
    print("2018-06-04")

f()

 

3.  带参数的装饰器

def test(m):        #获取参数
    def inner(func):
        def warpper(*args,**kwargs):
            print(m)     #打印该参数
            if m==1:    #判断该参数
                print("start")
                func(*args,**kwargs)
                print("end")
        return warpper
    return inner
  
@test(m=1)    #传入参数
def f():
    print("2018-06-04")

f()

 

4.  被装饰的函数有返回值怎么处理

         res=func(*args,**kwargs)

   return res

在执行该函数的时候 接收函数的返回值,并在其后return

5.  多个装饰器的执行顺序

装饰器函数的执行顺序是分为定义阶段和执行阶段的

        装饰器函数在被装饰函数定义好后立即执行

在函数定义阶段:执行顺序是从内而外的

在函数执行阶段:执行顺序由外而内,一层层执行

例子:如下  

def war1(func):
    print("war1")
    def inner(*args, **kwargs):
        print("======war1 start=====")
        func(*args, **kwargs)    #inner
        print("======war1 end=====")
    return inner

def war2(func):
    print("war2")
    def inner(*args,**kwargs):
        print("======war2 start=====")
        func(*args,**kwargs)
        print("======war2 end=====")
    return inner

@war1
@war2
def f():
    print("****self****")
f()
View Code

 

 

6.  装饰类的装饰器   

import settings

def singleton(cls): #cls=Mysql
    _instance=cls(settings.HOST,settings.PORT)

    def wrapper(*args,**kwargs):
        if args or kwargs:
            obj=cls(*args,**kwargs)
            return obj
        return _instance

    return wrapper


@singleton # Mysql=Singleton(Mysql)
class Mysql:
    def __init__(self,host,port):
        self.host=host
        self.port=port



obj1=Mysql()
类的装饰器实现单例模式

 

7. 被装饰函数的属性变化

 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。

from functools import wraps

def test(func):

#当函数被装饰器装饰时,自身的name以及doc都没有了

#,若想获得原来的值,需要加上了一句

 # 装饰器修复技术

    @wraps(func)   

    def warpper(*args,**kwargs):

        print("kaishi")

        func(*args,**kwargs)

        print("jieshu")

    return warpper

 

@test

def f():

    print("2018-06-04")

f()

print(f.__doc__)   # 如果不加装饰器的修复技术,打出的warpper函数的__doc__

print(f.__name__)  # 如果不修复,打出的是warpper
被装饰函数的属性变化

 

    

 

posted @ 2018-06-04 19:42  道友请多指教  阅读(168)  评论(0编辑  收藏  举报