zoukankan      html  css  js  c++  java
  • Python装饰器

    Python中的装饰器的概念经常会让人搞得一头雾水,所以今天就好好来分析一下python中的装饰器.

    先看一个简单的装饰器用法:

     1 def decorator(func):
     2     print("this is wrapper")
     3 
     4     def wrapper():
     5         func()
     6 
     7     return wrapper
     8 
     9 
    10 @decorator
    11 def func():
    12     print('this is func')
    13 
    14 # func()
    15 # print(func.__name__)

    运行一下上述代码,看看输出.再把14,15行的注释放开,看看输出.

    我们发现当14,15行注释掉时,输出this is wrapper。

    15行注释放开,你会发现先func()的名字变成了wrapper。

    @其实就是python中的一个语法糖.装饰器的本质以上述代码为例:

    @decorator
    def func():
        print('this is func')

    其实解释器执行了这么一句:func = decorator(func).这就是装饰器最本质最核心的东西了.

    func作为参数传递给decorator,decorator的返回值是wrapper(),赋给func.就这样被修饰的函数func其实已经变成了另一个函数wrapper了.

    下面我们就来看看几个例子:

    1.你想写这样一个装饰器:

    @decorator
    def func(user):
        print("this",user," func")

    要怎么写呢?

    我们来看看func = decorator(func).

    第一步:我们知道decorator(func)应该返回一个函数.所以有如下代码.

    def decorator(func):
        def wrapper():
            pass
            
        return wrapper    

    第二步:装饰器是用来装饰函数的,你不能把原有的要装饰的func(user)的功能给弄没了啊.所以我们补全wrapper()

    def decorator(func):
        def wrapper(user):
            print("start decorate",user)
            func(user)
        return wrapper

    这时候你要装饰的func(user)就变成wrapper(user)啦.

    完整代码:

    2.一个装饰器想装饰好几个函数.

    比如:

    @decorator
    def func(user):
        print(user)
    
    @decorator
    def func2(user1,user2):
        print(user1,"and",user2)

    要装饰的函数的参数你不确定有几个.可以用*args,**args表示任意参数就可以了.

    def decorator(func):
        def wrapper(*args,**kwargs):
            print("start decorate")
            func(*args)
        return wrapper
    
    @decorator
    def func(user):
        print(user)
    
    @decorator
    def func2(user1,user2):
        print(user1,"and",user2)
    
    func('tim')
    func2('joe','jimmy')

    3.多个装饰器修饰一个函数

    @decorator0
    @decorator1
    def func():
        print("this is func")

    实际上解释器执行func = decorator0(decorator1(func))

    可以分两步:

    1.decorator1(func)返回一个函数

    2.decorator0()接受一个函数作为参数,并返回一函数.

    所以就有了:

    def decorator1(func):
        def wrapper():
            print("decorator1!")
            func()
        return wrapper
    def decorator0(func):
        def wrapper():
            print("decorator0!")
            func()
        return wrapper

    完整代码

    #func = decorator0(decorator1(func))
    def decorator0(func):
        def wrapper():
            print("decorator0!")
            func()
        return wrapper
    
    def decorator1(func):
        def wrapper():
            print("decorator1!")
            func()
        return wrapper
    
    @decorator0
    @decorator1
    def func():
        print("this is func")
    
    print(func.__name__)
    func()

    4.装饰器带参数

    @decorator(num)
    def func(user):
        print(user)

    实际上解释器执行func = decorator(num)(func)

    也就是说你可以认为1.decorator(num)返回一个函数.2.返回的函数的类型是:以func为参数,返回值是一个函数.

    所以第一步:

    def decorator(num):
        def wrapper():
            pass
        return wrapper

    第二步:

    def decorator(num):
        def wrapper(func):
            def wrapper2(user):
                print(num)
                func(user)
            return wrapper2
        return wrapper


  • 相关阅读:
    自己定义button
    Google C++ style guide——格式
    杭电1018-Big Number(大数)
    AnyForWeb告诉你什么才是“最好的”编程语言
    Android广播机制分析
    nyoj Wythoff Game(暴力枚举)
    基础搜索入门(二)
    1.1、Libgdx目标和特性
    我在农业2.0的互联网创业思考 (1)
    Python演绎的精彩故事(二)
  • 原文地址:https://www.cnblogs.com/sdu20112013/p/4041790.html
Copyright © 2011-2022 走看看