• Python函数-6 装饰器


    装饰器
    装饰器(Decorator):从字面上理解,就是装饰对象的器件。可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将@装饰器名,放在被装饰对象上面。

    @dec
    def func():
        pass
    

    在介绍装饰器之前,先要了解几个知识点

    重名函数会怎么样?

    def test():
    	print('1')
    def test():
    	print('2')
    test()
    这个时候会输出什么?
    会输出2,后面的会覆盖前面的函数
    -----------------------------------
    def foo():
    	print('test')
    foo = lambda x:x+1
    foo()
    此时foo()的执行结果是什么?
    foo会执行匿名函数的内容,而不会执行函数foo,打印test
    

    接下来就是一个比较经典的案例了,有一个大公司,下属的基础平台部负责内部应用程序及API的开发。另外还有上百个业务部门负责不同的业务,这些业务部门各自调用基础平台部提供的不同函数,也就是API处理自己的业务,情况如下:
    基础平台部门提供的功能如下:

    def f1():
    	print("业务部门1的数据接口......")
    def f2():
    	print("业务部门2的数据接口......")
    def f3():
    	print("业务部门3的数据接口......")
    def f100():
    	print("业务部门100的数据接口......")
    各部门分别调用基础平台提供的功能
    f1()
    f2()
    f3()
    f100()
    

    目前公司发展壮大,但是以前没有考虑到验证相关的问题,即:基础平台提供的功能可以被任何人使用。现在需要对基础平台的所有功能进行重构,为平台提供的功能添加验证机制,执行功能前,先进行验证 老大把工作交给A,他是这么做的: 跟每个业务部门交涉,每个业务部门自己写代码,调用基础平台的功能之前先验证。这样一来基础平台就不需要做任何修改了。 当前A被老大开除了 老大又把工作交给B,他是这么做的:

    def f1():
        # 验证1
        # 验证2
        # 验证3
    def f2():
        # 验证1
        # 验证2
        # 验证3
    过了一周B也被开除了。。。。。。。。。。
    

    老大又把工作交给C,他是这么做的:

    def check_login()
        # 验证1
        # 验证2
        # 验证3
    def f1():
    	check_login()
    def f2():
    	check_login()	
    

    老大说写代码要遵循开放封闭的原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,已经实现的功能不允许修改,但可以被扩展 。

    封闭:已实现的功能代码块

    开放:对扩展开发

    老大给出了方案,
    def foo():
    	def inner():
        	验证1
        	验证2
        	验证3
    	    result = func()
    	    return result
    return inner
    
    @foo
    def f1():
    	pass
    @foo
    def f2():
    	pass
    

    看不懂?没关系,接下来写一个简单点的

    def w1(func):
    	def inner():
    		print('正在验证权限')
    		func()
    	return inner
    	
    def f1():
    	print('f1')
    
    innerFunc = w1(f1)        # innerFunc = inner
    innerFunc()               # inner()
    
    f1 = w1(f1)
    f1()
    
    def outer(func):
        def inner():
            print("认证成功!")
            result = func()
            print("日志添加成功")
        return inner
    
    @outer              # f1 = outer(f1) = inner
    def f1():
        print("业务部门1数据接口......")
    
    f1()    
    
    1 程序开始运行,从上往下解释,读到def outer(func):的时候,发现这是个“一等公民”函数,于是把函数体加载到内存里,然后过。
    2 读到@outer的时候,程序被@这个语法糖吸引住了,知道这是个装饰器,按规矩要立即执行的,于是程序开始运行@后面那个名字outer所定义的函数。
    3 程序返回到outer函数,开始执行装饰器的语法规则。
    规则是:被装饰的函数的名字会被当作参数传递给装饰函数。装饰函数执行它自己内部的代码后,会将它的返回值赋值给被装饰的函数。原来的f1函数被当做参数传递给了func,而f1这个函数名之后会指向inner函数
    

    两个装饰器

    def makeBold(fn):
        def wrapped():
            return "<b1>" + fn() + "</b1>"
        return wrapped
    
    def makeItalic(fn):
        def wrapped():
            return "<b2>" + fn() + "</b2>"
        return wrapped
    
    
    
    @makeBold       # test3 = makeBold(test3)   =  wrapped
    @makeItalic     # test3 = makeItalic(test3) =  wrapped
    def test3():
        return "hello world"
    
    print(test3())
    

    装饰器的执行时间

    def w1(func):
        print("--正在装饰--")
        def inner():
            print("--正在权限验证--")
            func()
        return inner
    
    # 只要Python解释器执行到了这个代码,那么就会自动的进行装饰,而不是等到调用的时候才进行装饰
    @w1     # f1 = w1(f1)
    def f1():
        print("--f1--")
    
    # 在调用f1前已经装饰了
    f1()
    

    练习

    def w1(func):
        print("正在装饰1")
        def inner():
            print("正在验证权限1")
            func()
        return inner()
    
    def w2(func):
        print("正在装饰2")
        def inner():
            print("正在验证权限2")
            func()
        return inner()
        
    @w1
    @w2
    def f1():
        print("--f1--")
    f1()
    
  • 相关阅读:
    Bit Manipulation
    218. The Skyline Problem
    Template : Two Pointers & Hash -> String process
    239. Sliding Window Maximum
    159. Longest Substring with At Most Two Distinct Characters
    3. Longest Substring Without Repeating Characters
    137. Single Number II
    142. Linked List Cycle II
    41. First Missing Positive
    260. Single Number III
  • 原文地址:https://www.cnblogs.com/sakura579/p/12422159.html
Copyright © 2020-2023  润新知