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',再输出'好'。

    三样东西有助于缓解生命的疲劳:希望、睡眠和微笑。---康德
  • 相关阅读:
    BZOJ 2212/BZOJ 3702
    BZOJ 4761 Cow Navigation
    BZOJ 3209 花神的数论题
    BZOJ 4760 Hoof, Paper, Scissors
    BZOJ 3620 似乎在梦中见过的样子
    BZOJ 3940 Censoring
    BZOJ 3942 Censoring
    BZOJ 3571 画框
    BZOJ 1937 最小生成树
    BZOJ 1058 报表统计
  • 原文地址:https://www.cnblogs.com/ronghe/p/8681358.html
Copyright © 2011-2022 走看看