zoukankan      html  css  js  c++  java
  • Python之路【第十七篇】:装饰器

    写代码的时候有一个原则,开放封闭原则(面向对象):对某些东西开放,对某些封闭,在装饰器这里,函数内部是封闭的,不允许改变函数的内部。

    装饰器用来装饰函数,可以让函数在执行之前或者执行之后,做一些操作,让函数调用者的操作不变,就能在执行前后做一些操作。简单来说,装饰器感觉就类似于装修,提供一些额外的功能。

    装饰器的本质就是将原函数封装到另一个函数里面。

    装饰器原理剖析

    关键点1

    def f1():
        print('1')
    def f1():
        print('2')
    f1()

    上面这段函数执行后,输出的结果为2,因为python解释器从上往下执行,先把第一个f1放进内存,碰到第二个f1函数后又把它放进内存,所以f1指的是第二个函数的内容。

    关键点2

    @符号:

        @符号具有特殊性,@函数名,碰到后,先执行函数,并且将其下面的函数名当作参数,如:

    def outer(func):
        pass
    @outer
    def f1():
        pass
    def f2():
        pass

    碰到@outer之后,先执行outer函数,然后将f1作为参数,此时func=f1(原来的f1函数)

    outer的返回值赋值给f1,此时f1=outer返回值,所以以后再执行f1,就执行新的f1函数

     关键点3

    只要函数用了装饰器,函数就会重新定义为装饰器的内层函数,所以如果函数有参数的话,装饰器的内层函数也要有相应的参数来接收,即inner函数要有相应的参数,同时,func函数等于原来的函数,所以func函数也要有相应的参数

    inner(*args,**kwargs)

    ret  = func(*args,**kwargs)

    以后写装饰器就按照上面的写法来,这样就不用担心参数的问题了,碉堡了。

    装饰器例子:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    def outer(func):
        def inner(*args,**kwargs):
            print('')
            ret = func(*args,**kwargs)
            print('')
            return ret
        return inner
    
    @outer
    def f1(a1):
        print('aa')
        return a1
    
    @outer
    def f2(s1,s2):
        print('bb')
        return s1,s2
    
    ret1 = f1(1)
    
    ret2 = f2(2,3)
    
    print(ret1,ret2)

    上面的程序输出结果为:


    aa


    bb

    1 (2, 3)

    可以看到,在不改变函数的基础上,函数执行了一些别的操作。上面这是一个装饰器装饰一个或多个函数的场景

    多个装饰器装饰一个函数

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    def outer0(func):
        def inner(*args,**kwargs):
            print('before')
            ret = func(*args,**kwargs)
            print('after')
            return ret
        return inner
    def outer(func):
        def inner(*args,**kwargs):
            print('')
            ret = func(*args,**kwargs)
            print('')
            return ret
        return inner
    @outer0
    @outer
    def f1():
        print('self')
        return None
    f1()

    输出结果为:

    before

    self

    after

    可以这样理解:

    #part1
    #一个新的函数,不妨叫这个函数为index
    @outer
    def f1(): print('self') return None

    然后代码就变成了下面这样:

    #part2
    @outer0 def index(): pass

    最后函数的执行顺序是这样的:先执行最外层的part2,即先输出before,在执行index函数,最后输出after,执行index函数的时候,就是执行part1,先输出'你',在输出'self',再输出'好'。

    三样东西有助于缓解生命的疲劳:希望、睡眠和微笑。---康德
  • 相关阅读:
    PAT甲级1114. Family Property
    PAT甲级1111. Online Map
    Android零基础入门第84节:引入Fragment原来是这么回事
    Android零基础入门第83节:Activity间数据传递方法汇总
    Android零基础入门第82节:Activity数据回传
    Android零基础入门第81节:Activity数据传递
    Android零基础入门第80节:Intent 属性详解(下)
    Android零基础入门第79节:Intent 属性详解(上)
    Android零基础入门第78节:四大组件的纽带——Intent
    Android零基础入门第77节:Activity任务栈和启动模式
  • 原文地址:https://www.cnblogs.com/ronghe/p/8681358.html
Copyright © 2011-2022 走看看