python装饰器详解(二)---实现装饰器

时间:2021-11-16 22:26:44
装饰器就是把其他函数作为参数的函数

def my_shiny_new_decorator(a_function_to_decorate):
   
# 在函数里面,装饰器在运行中定义函数: 包装.
 
  # 这个函数将被包装在原始函数的外面,所以可以在原始函数之前和之后执行其他代码..
   
def the_wrapper_around_the_original_function():
       
# 把要在原始函数被调用前的代码放在这里
       
print ( "Beforethe function runs" )

       
#调用原始函数(用括号)
       
a_function_to_decorate()

       
#把要在原始函数调用后的代码放在这里
     
  
print ( "After the function runs" )
   
# 在这里"a_function_to_decorate" 函数永远不会被执行
   
# 在这里返回刚才包装过的函数
   
# 在包装函数里包含要在原始函数前后执行的代码.

    return the_wrapper_around_the_original_function


假如你建了个函数,不想修改了
defa_stand_alone_function():

    print("Iam a stand alone function , don't yyou dare modify me")

a_stand_alone_function()
#输出: I am a stand alone function, don't you dare modifyme

现在,你可以装饰它来增加它的功能,把它传递给装饰器,它就会返回一个被包装过的函数.

a_stand_alone_function_decorated =my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()

#输出s:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

    现在,你或许每次都想用a_stand_alone_function_decorated代替a_stand_alone_function,很简单,只需要用my_shiny_new_decorator返回的函数重写a_stand_alone_function:

a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)

a_stand_alone_function()

#输出:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

上述即为装饰器的作用!!!!


装饰器语法:

@my_shiny_new_decorator
def another_stand_alone_function():
    print("Leave me alone")

another_stand_alone_function()
#输出: #Before the function runs #Leave me alone #After the function runs

@decorator就是下面的简写:

another_stand_alone_function =my_shiny_new_decorator(another_stand_alone_function)

    装饰器就是decorator design pattern的pythonic的变种.在Python中有许多经典的设计模式来满足开发者.


看下面的例子:

def bread(func):
    def wrapper():
        print("</''''''/>")
        func()
        print("</''''''/>")
    return wrapper
def ingredients(func):
    def wrapper():
        print("#tomatoes#")
        func()
        print("~salad~")
    return wrapper

def sandwich(food="--ham--"):
   
print(food)

执行

sandwich()

输出

# --ham--

执行

sandwich = bread(ingredients(sandwich))
sandwich()

输出

#</''''''\>

# #tomatoes#

# --ham--

# ~salad~

#<\______/>


用装饰器实现

@bread
@ingredients
def sandwich(food = "--ham--"):
    print("food")

执行

sandwich()

输出

#</''''''\>

# #tomatoes#

# --ham--

# ~salad~

#<\______/>

改变一下顺序:

@ingredients
@bread

def sandwich(food = "--ham--"):
    print("food")

执行

sandwich()

输出

##tomatoes#

#</''''''\>

# --ham--

#<\______/>

# ~salad~


结论:装饰器先写后调用,靠近里层的先调用,就像包装一样