例解什么是Python装饰器

Python中的装饰器一直是一个比较难理解的概念,我自己理解的就是用一个函数去修改另一个函数,主要是为另一个函数添加计时等功能,而且不用改变另一个函数,这样就大大减少了另一个函数的维护成本。

这个装饰器,英文名就是decorator,相关于把一个写好的程序添加一些新的功能,让这个程序变成多功能的。装饰器还可以传递参数,但如果要加参数就要多一层。

首先,我们看一个样例[1],有一个计算数字平方和的函数,我们添加一个装饰器elasped,来为它增加计算函数运行时间的功能。

一、不用@添加装饰器的写法

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed(target):
    "统计函数执行的耗时:"
    def decorated(*args,**kwargs):
        start = time.time()
        r = target(*args,**kwargs)
          
        end = time.time()
        print("函数执行耗时:", round(end - start, 2))
        return r
    return decorated

def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    power_sum = elapsed(power_sum) # 相当于用装饰器函数elapsed调用了power_sum函数
    print(power_sum(1000000))

二、使用@加装饰器的调用方法

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed(target):
    "统计函数执行的耗时:"
    def decorated(*args,**kwargs):
        start = time.time()
        r = target(*args,**kwargs)
          
        end = time.time()
        print("函数执行耗时:", round(end - start, 2))
        return r
    return decorated

@elapsed   # 相当于用装饰器函数elapsed调用了power_sum函数相当于这行代码:power_sum = elapsed(power_sum)
def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    print(power_sum(1000000))

调用结果:

例解什么是Python装饰器_第1张图片

三、为装饰器加上参数的方法

现在为装饰器加上参数,把函数执行耗时的时间加上可以控制保留小数位数的参数precision,结果如下:

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed_precision(precision):
    def elapsed(target):
        "统计函数执行的耗时:"
        def decorated(*args,**kwargs):
            start = time.time()
            r = target(*args,**kwargs)
              
            end = time.time()
            print("函数执行耗时:", round(end - start, precision))
            return r
        return decorated
    return elapsed

#不写就没有装饰器效果,写了相当于这一句:power_sum = elapsed(power_sum) 也就是power_sum被装饰后又重新命名为power_sum函数
@elapsed_precision(3)# 这里的3就是装饰器的参数。
def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    print(power_sum(10000000))

由上述代码可见,我们加装饰器后,原来的函数没有变化,我们只是通过装饰器给power_sum函数添加计时功能,传递了一个保留小数位数的参数precision。

四、学后反思

1. 装饰器是python学习中一个比较难理解的概念,因为我们一直把函数的参数局限为字符、列表、元组、字典这些常用的数据结构,但是如果我们把函数看成一个对象,把一个函数作为另一函数(装饰器)的参数来调用就好理解了。
2. 装饰器可以使Python编写的代码更容易维护,同时也可以为函数增加更多的功能,是Python程序编写过程中一个重要的工具。
3. 在我学习Python的过程中,我一直对装饰器、多线程、异步这些概念模糊不清楚。虽然也有意去学习,但很多时候是一知半解,后来通过B站学习和个人的思考慢慢把这些概念理解弄通。

你可能感兴趣的:(python,编程小项目,python,开发语言)