• python 装饰器


    一、装饰器定义。

    装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短。

    应用场景:

      假如:此时写了很多函数,有一个新的需求需要在多个函数中添加或者修改一个功能,如果每个函数都修改一次显得太过繁重,此时装饰器就出现了。

      首先定义一个装饰器,写好要修改或者添加的功能,每个函数前用@装饰器名称,即可调用装饰器函数。

    定义一个装饰器:

    def outer(func):
    def inner():
    print "start"
    r = func() # r = None
    print "end"
    return r
    return inner # 注意:返回的只是函数名,不是inner()

    定义一个函数,并引用装饰器:

    @outer  # 引用装饰器
    def faa():
        print ("faa")
    
    a = faa()
    print a

    查看执行结果

    start
    faa
    end

    从执行结果我们可以看出装饰器的执行顺序,先执行装饰器的部分功能,再执行普通方法中,然后执行装饰器其它代码,顺序可以根据需求调整。

    “@”作用:

    •  执行outer函数,并将@下面的函数名传给outer函数,当做参数。
    •  将outer函数的返回值重新赋值给faa faa=outter的返回值
    •  本质上:相当于在原来的函数faa的基础上,前后增加了一些操作。将原函数封装到另外一个函数上,并将返回值重新赋值给原函数、

    二、装饰器加参数。

    装饰器内部调用函数时,假如函数需要传参,那么以上代码无法满足传参的需求。

    def outer(func):
        def inner(a1,a2):
            print "==== start ====="
            r = func(a1,a2)
            print "==== end ===="
            return r
        return inner
    
    @outer
    def faa(a1,a2):
        print "普通函数中的功能"
    
    # ============= 执行结果 ================
    ret = faa("a","b")
    print ret

    以上代码即可实现传参功能。

    但是我们会发现这样传参很不灵活,既假如还有其它函数需要传参,而传参的个数或者参数的类型不一样,那么以上代码则无法满足其它函数传参。

    三、装饰器传多个参数

     普通函数传多个参数:

    def fun(*args,**kwargs):
        print args
        print kwargs
    
    fun("a1","a2",k1="steven",k2="18")
    
    # ============= 返回结果 ==============
    ('a1', 'a2')
    {'k2': '18', 'k1': 'steven'}

    装饰器传参

    def outer(func):
        def inner(*args,**kwargs):
            print  "=" * 20
            print "装饰器 start"
            r = func(*args,**kwargs)
            print "装饰器,end"
            return r
        return inner
    
    @outer
    def fun1(a1):
        print "fun1 一个参数"
    
    @outer
    def fun2(a1,a2):
        print "fun2 两个参数"
    
    @outer
    def fun3(*args,**kwargs):
        print args
        print kwargs
    
    ret1 = fun1("f1_a1")
    ret2 = fun2("f2_a1","f2_a2")
    ret3 = fun3("f3_a1","f3_a3",k1="k1",k2="k2")
    
    
    
    ============ 返回结果 ==============
    
    装饰器 start
    fun1 一个参数
    装饰器,end
    ====================
    装饰器 start
    fun2 两个参数
    装饰器,end
    ====================
    装饰器 start
    ('f3_a1', 'f3_a3')
    {'k2': 'k2', 'k1': 'k1'}
    装饰器,end

     四、添加多个装饰器

    def outer(func):
        def inner(*args,**kwargs):
            print "="*20
            print "装饰器outer start"
            r = func(*args,**kwargs)
            print "装饰器outer end"
            return r
        return inner
    
    def outer_1(func):
        def inner(*args,**kwargs):
            print '='*20
            print "装饰器outer_1 start"
            r = func(*args,**kwargs)
            print "装饰器outer_1 end"
            return r
        return inner
    
    @outer
    @outer_1
    def fun1(a1):
        print "fun1"
    
    f1 = fun1("多个装饰器")
    
    
    # =========== 返回值 =====================
    
    
    ====================
    装饰器outer start
    ====================
    装饰器outer_1 start
    fun1
    装饰器outer_1 end
    装饰器outer end
  • 相关阅读:
    js中==与===区别
    Initialization failure 0x0000000c
    Spring通过@Value注解注入属性的几种方式
    java中读取配置文件中数据的具体方法
    spring整合hibernate
    url上参数解析笔记
    编号的生成(日期+序列号)
    application.xml & -servlet.xml
    webApplicationContext 与servletContext
    Http协议整理
  • 原文地址:https://www.cnblogs.com/sunshine-long/p/12489757.html
Copyright © 2020-2023  润新知