首页 > 技术文章 > python语法糖

leishenwudi 2020-09-11 22:24 原文

python的语法糖就是对指定的目标函数进行装饰。

要想先了解装饰器,就必须先知道闭包

python函数的闭包实际上就是一个函数,其传入的参数是一个函数,返回的仍然是一个函数

例如:

import time
def after_add(func):
    def add_thing():
        print('----装饰前------')
        func()
        print('----装饰后------')
    return add_thing
def add_1():
    print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
    add_2 = after_add(add_1)
    add_2()

这里after_add就形成了一个闭包

那如何形成一个装饰器?装饰器其实跟闭包相似,只是装饰器没有将新函数传给一个变量,然后再调入,而是一气呵成

装饰器相当于  add_2 = after_add(add_1)

所以代码可以等价于

import time
def after_add(func):
    def add_thing():
        print('----装饰前------')
        func()
        print('----装饰后------')
    return add_thing
@after_add
def add_1():
    print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
    add_1()

 

 这里就跟前面的闭包一样,就跟 add_2 = after_add(add_1)这样分析,先进入after_add(),先定义了函数,然后再得到新函数,接着再调用得到的函数,所以最后才打印这个结果

如果像这样

import time
def after_add(func):
print(11)
def add_thing():
print('----装饰前------')
func()
print('----装饰后------')
return add_thing
@after_add
def add_1():
print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
add_1()

 

 加入print(11),所以先打印了11

记住两个原则:

1、装饰器在函数调用之前被增强

2、相同的函数只被增强一次

 

下面看一下带参数的装饰器

目标函数的参数供自己使用,就例如

import time
def say_thing(func):
    def say_say(name):
        print("Hello")
        func(name)
    return say_say

@say_thing
def say_name(name):
    print(name)
say_name('Li Ming')

这里注意say_say这里也需要带参数,因为装饰器最后调用的是增强后的say_say,需要通过增强函数将参数传给目标函数.

这里还注意一点就是如果有多个装饰器,它是从内往外增强的

 

推荐阅读