Python 如何理解又晕又好用的装饰器

Python 装饰器这东西对初学者来说是个坑,很容易绕晕,笔者当时初学装饰器时花费了数天时间,看了不同讲师对这块内容的讲解,还是一知半解。

不过装饰器在开发中可是很好用的,有必要攻破,希望这篇文章能帮助学习者快速攻破难关。

初步理解

# 先来看一个简单函数

def show():
    print (‘Mr tu‘)

show()

# 执行结果 :

Mr tu

# 现在我们用装饰器扩展这个函数,在打印 " Mr tu " 之前打印一行 " hello "  

def decorate(fun1):
    def wapper():
        print(‘hello‘)
        fun1()
    return wapper

@decorate
def show():
    print (‘Mr tu‘)

show()

# 执行结果 :

hello
Mr tu

# 现在解释上面的代码。

# 1、首先 def decorate(fun1) 定义一个装饰器函数,在此函数里又定义了一个wapper子函数,子函数可以继承父函数的参数。

# 2、 @‘函数名‘是Python的一种语法糖 @decorate 等于 decorate(show) 

# 还是晕,不明白?  没关系,看下面代码:

def decorate(fun1):
    def wapper():
        print(‘hello‘)
        fun1()
    return wapper

def show():
    print (‘Mr tu‘)

f1 = decorate(show)
f1()

# 执行结果 :

hello
Mr tu

# 换成这种写法,执行效果是一样的,因为这就是 @decorate 的本质。

# 就是将被装饰器装饰的函数show作为参数传给装饰器函数。

# 总结执行过程:

# 1、show函数作为参数传给装饰器函数 decorate ,那么 fun1 = show

# 2、这时执行到装饰器的子函数 wapper,子函数可以继承父函数的参数,所以可以调用 fun1 

# 3、然后wapper函数执行 print 打印一行 "hello" , 再然后  调用fun1() —— 这里其实就是执行了show函数。  因为在装饰器一开始执行的时候就把show函数作为参数赋值给了fun1.

# 现在明白了吧,只要这里明白,下面的就很好理解了。

装饰带参数的函数

# 一个参数

def decorate(fun1):
    def wapper(arg1):
        print(‘hello‘)
        fun1(arg1)
        print(‘nice to meet you‘)
    return wapper

@decorate
def show(arg1):
    print (arg1)

    
show(‘Mr Alice‘)

# 执行结果:

hello
Mr Alice
nice to meet you

# 两个参数

def decorate(fun1):
    def wapper(arg1,arg2):
        print(‘hello‘)
        fun1(arg1,arg2)
        print(‘nice to meet you‘)
    return wapper

@decorate
def show(arg1,arg2):
    print (arg1,arg2)

show(‘Mr Alice‘,‘Mr Tom‘)

# 执行结果:

hello
(‘Mr Alice‘, ‘Mr Tom‘)
nice to meet you

# n个参数

def decorate(fun1):
    def wapper(*args,**kwargs):
        print(‘hello‘)
        fun1(*args,**kwargs)
        print(‘nice to meet you‘)
    return wapper

@decorate
def show(*args,**kwargs):
    print (args[0])
    print (args[1])
    print (args[2])

show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘)

# 执行结果:

hello
Mr Alice
Mr Tim
Mr tu
nice to meet you

一个函数被多个装饰器装饰

def decorate01(fun1):
    def wapper(*args,**kwargs):
        print(‘hello world‘)
        print(‘I am decorate01‘)
        fun1(*args,**kwargs)
    return wapper

def decorate02(fun1):
    def wapper(*args,**kwargs):
        print (‘I am decorate02‘)
        fun1(*args,**kwargs)
        print(‘nice to meet you‘)
    return wapper

@decorate01
@decorate02
def show(*args,**kwargs):
    print (args[0])
    print (args[1])
    print (args[2])

show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘)

# 执行结果:

hello world
I am decorate01
I am decorate02
Mr Alice
Mr Tim
Mr tu
nice to meet you

# 观察print放置的位置不同,对应的输出结果不同。

def decorate01(fun1):
    def wapper(*args,**kwargs):
        print(‘hello world‘)
        fun1(*args,**kwargs)
        print(‘I am decorate01‘)  # 替换到了下面
    return wapper

def decorate02(fun1):
    def wapper(*args,**kwargs):
        print (‘I am decorate02‘)
        fun1(*args,**kwargs)
        print(‘nice to meet you‘)
    return wapper

@decorate01
@decorate02
def show(*args,**kwargs):
    print (args[0])
    print (args[1])
    print (args[2])

show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘)

# 执行结果:

hello world
I am decorate02
Mr Alice
Mr Tim
Mr tu
nice to meet you
I am decorate01

装饰器功能扩展

#!/usr/local/python27/bin/python2.7

def before(request,*args,**kwargs):
    print(‘before‘)

def after(request,*args,**kwargs):
    print(‘after‘)

def Filter(before_func,after_func):
    def outer(fun1):
        def wapper(request,*args,**kwargs):

            before_result = before_func(request,*args,**kwargs)
            if(before_result != None):
                return before_result;

            fun1_result = fun1(request,*args,**kwargs)
            if(fun1_result != None):
                return fun1_result;

            after_result = after_func(request,*args,**kwargs)
            if(after_result != None):
                return after_result;

        return wapper
    return outer

@Filter(before,after)
def show(request,*args,**kwargs):
    print (‘Mr tu‘)

    
show(‘1‘)

# 执行结果:

before
Mr tu
after

函数若未定义返回值,执行成功返回值默认为 None ,这里的语句 if (before_result != None) 意思就是before函数执行失败时采取什么操作。

时间: 2024-10-07 15:31:22

Python 如何理解又晕又好用的装饰器的相关文章

Python学习笔记8(迭代器、生成器、装饰器)

1.列表生成式 要想学习生成器和迭代器,首先得了解另外一个概念,列表生成式. 想要生成一个0~9的列表的时候,首先想到的就是range(0,10) >>>a = range(0,10) >>>print(a) #3.0输出结果 range(0,10) #2.0输出结果 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 在3.0的版本呢当中range只是用来生成一个迭代器了,但是在2.0的版本里可以使用range来快速生成list. 但是想要生成一个[1*1,

Python学习之路day4-函数高级特性、装饰器

一.预备知识 学习装饰器需理解以下预备知识: 函数即变量 函数本质上也是一种变量,函数名即变量名,函数体就变量对应的值:函数体可以作为值赋给其他变量(函数),也可以通过函数名来直接调用函数.调用符号即(). 嵌套函数 函数内部可以嵌套定义一层或多层函数,被嵌套的内部函数可以在外层函数体内部调用,也可以作为返回值直接返回 闭包 在一个嵌套函数中,内部被嵌套的函数可以调用外部函数非全局变量并且不受外部函数声明周期的影响(即可以把外部函数非全局变量视为全局变量直接调用). 高阶函数 把一个函数作为参数

python学习之路-4 内置函数和装饰器

本篇涉及内容 内置函数 装饰器 内置函数 callable()   判断对象是否可以被调用,返回一个布尔值 1 2 3 4 5 6 7 8 9 10 11 num = 10 print(callable(num))   # num不能够被调用,返回False    def f1():     print("name")    print(callable(f1))     # f1可以被调用,返回True    # 输出 False True ?chr()   将十进制整数转换为asc

python学习笔记4:高阶函数,装饰器,生成器,迭代器

一.高级函数1.把一个函数名当作实参传给另一个函数2.返回值包含函数名>>> def bar():... print ("in the bar")... >>> def foo(func):... res=func()... return res... >>> foo(bar)in the bar 二.嵌套函数在函数中定义另一个函数 三.装饰器装饰器本质上是函数,作用是装饰其他函数,就是为其他函数添加附加功能.原则1:不能修改被装饰

Python基础篇【第九篇】:剖析装饰器

装饰器:装饰器:装饰器的语法以@开头,然后是装饰器函数的名字和可选的参数,紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数.剖析装饰器: #!/usr/bin/env python3 ''' 装饰器:装饰器的语法以@开头,然后是装饰器函数的名字和可选的参数,紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数. 表现形式: def outer(): def inner(): print("xxx") return test return inner @outer def f1():

python学习笔记7:装B神器之装饰器

参考:http://www.cnblogs.com/wupeiqi/articles/4980620.html 1.必备 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #### 第一波 #### def foo():     print 'foo' foo     #表示是函数 foo()   #表示执行foo函数 #### 第二波 #### def foo():     print 'foo' foo = lambda x: x + 1 foo()   # 执行下面的lam

Python笔记·第十一章—— 函数 (二) 装饰器

一 为何要用装饰器 有的时候写完一段代码,过段时间需要对它进行升级.添加一些新功能,但是如果要直接修改原来的代码会影响其他人的调用,所以就需要一个不修改源代码且不修改原函数的调用方式的东西又能为原函数增添新功能的东西,装饰器就是干这个的. 二 什么是装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能 开放封闭原则:对修改封

python基础6—(高阶,匿名,偏)函数 | 装饰器

这里比较的高级了, 学到这里感觉有点意思,但是也看到了和其他语言相通点 高阶函数 可以把别的函数作为参数传入的函数叫高阶函数 def add(x, y, f): return f(x) + f(y) add(-5, 6, abs) # 11 # 匿名函数 python使用lambda来创建匿名函数 sum = lambda arg1, arg2 : arg1 + arg2 sum(10, 20) # 30 # reduce 内建函数是个二元操作函数, 用来将一个数据集合所有数据进行二元操作 #

python中面向切片编程(AOP)和装饰器

@函数名(类的描述符)相当于fuc = decorator(fuc) 装饰器: def deco(fuc): print('============') return fuc @deco def foo(): print('foo函数正在运行') foo() 利用描述符自定制property class Decorator: def __init__(self, fuc): self.fuc = fuc def __get__(self, instance, owner): print('这里是