• python成长之路【第四篇】:装饰器


    实现装饰器的知识储备:

    示例:
    	def f1():
    		print("f1")
    
    1、函数即“变量”
    	#上面的示例中,函数f1为变量,它指向内存地址。而f1()表示函数执行。
    2、高阶函数
    	a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)。
    	b:返回值中包含函数名(不修改函数的调用方式)。
    3、嵌套函数
    	将一个函数放在另外一个函数里面。
    	
    装饰器 = 高阶函数 + 嵌套函数

    装饰器定义:本质是函数。(装饰其他函数)就是为其他函数添加附加功能。
    装饰器原则:

      1、不能修改被装饰的函数的源代码。
      2、不能修改被装饰的函数的调用方式。

    装饰器代码剖析:

    假如A公司有这么一个需求,公司临时规定将某块业务加上访问权限,因为代码太多,又不想改变原有封装好的代码,于是码农提出一个解决方法:装饰器。

    原始代码:

    def f1():
        #print("welcome to login...")  #需求是在这块加上验证
        print("f1...")
    f1()   #执行函数

    添加一个验证模块后,功能是实现了,但是改变了原有的调用方式:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #author chenjing
    
    def auth_login(func):   #func = f1
        def inner():
            print("welcome to login...")   #验证的内容加载这里
            func()     #func() = f1(),相当于执行f1()
        return inner    #返回inner函数体
    
    def f1():
        #print("welcome to login...")  #需求是在这块加上验证
        print("f1...")
    
    result = auth_login(f1)   #等于inner函数(包括它下面那一段代码)
    result()    #执行函数

    继续修改,保证原有的调用方式不受影响。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #author chenjing
    
    def auth_login(func):   #func = f1
        def inner():
            print("auth user ...")   #认证模块
            func()     #func() = f1(),相当于执行f1()
        return inner    #返回inner函数体
    
    @auth_login    #@auth_login是Python默认封装好的一种方法,它就是装饰器,功能相当于result = auth_login(f1)
    def f1():
        print("I'm f1")
    
    f1()    #执行函数 

    输出结果:

    auth user ...
    I'm f1

    到目前为止,f1业务好像已经完成了,这时f2业务又提了一个需求,f2调用时,需要往函数里面传递一个参数。coding...

    那么怎么办呢?那我们定义另外一个装饰器,而这个装饰器是可以接收参数的。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #author chenjing
    
    def auth_login(func):   #func = f1
        def inner():
            print("auth user ...")   #认证模块
            func()     #func() = f1(),相当于执行f1()
        return inner    #返回inner函数体
    
    def auth_login_arg(func):
        def inner(arg):
            print("auth user arg...")
            func(arg)
        return inner
    
    @auth_login    #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1)
    def f1():
        print("I'm f1")
    f1()    #执行函数
    
    @auth_login_arg    #调用新装饰器
    def f2(arg):    #参数
        print("I'm f2",arg)
    f2("new programs")  #传入参数

    输出结果:

    auth user ...
    I'm f1
    auth user arg...              #请看f2函数的输出
    I'm f2 new programs

    到目前为止,f2业务好像已经完成了,这时f3业务又提了一个需求,f3调用时,需要往函数里面传递几个参数。coding...

    这。。。程序员果然不是人干的。。我们还是看下面代码吧。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #author chenjing
    
    def auth_login(func):   #func = f1
        def inner():
            print("auth user ...")   #认证模块
            func()     #func() = f1(),相当于执行f1()
        return inner    #返回inner函数体
    
    def auth_login_arg(func):
        def inner(arg):
            print("auth user arg...")
            func(arg)
        return inner
    
    def auth_login_args(func):
        def inner(*args,**kwargs):    #动态参数
            print("auth user...")    #认证模块
            func(*args,**kwargs)    #动态参数
        return  inner
    
    @auth_login    #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1)
    def f1():
        print("I'm f1")
    f1()    #执行函数
    
    @auth_login_arg    #调用新装饰器
    def f2(arg):    #参数
        print("I'm f2",arg)
    f2("new programs")  #传入参数
    
    @auth_login_args
    def f3(name,age):
        print("I'm f3...",name,age)
    f3("Colin Chen",18)

    输出结果:

    auth user ...
    I'm f1
    auth user arg...
    I'm f2 new programs
    auth user...
    I'm f3... Colin Chen 18

    完美。需求都完成了,心情那叫一个好。

  • 相关阅读:
    C#批量附加指定目录下的所有数据库文件到数据库中
    UDP聊天代码发送消息客户端代码
    IE6 中 a:hover 的bug
    HTML 里的 if 条件用法
    How to Implement Ajax in WordPress Themes
    如何顺利的通过高级职称评审(转)
    WEB前端工程师如何做职业规划?(转)
    去掉IE浏览器里的脚本控件提示
    网页的横向滚动条
    Top 10 CSS Table Designs(转)
  • 原文地址:https://www.cnblogs.com/wooya/p/5781936.html
Copyright © 2020-2023  润新知