Python入门学习(九)Python的高级语法与用法(四)装饰器

一、从一个简单问题引入装饰器的作用由来

import time

def f1():
    print(time.time())   #输出unix时间戳
    print("This is the f1 function.")

f1()
#f1()函数很简单,实现一句话的打印
#如果要获取执行函数的时间,则按上述加入time()代码
#如果有很多函数都有增加时间戳的需求,如下面的f2()
def f2():
    print("This is the f2 function.")

#难道都进入函数定义去修改代码吗?
#函数理应对修改是封闭的,对扩展是开放的
#那么按如下思路则可以实现扩展
#将扩展功能单独作为一个函数,将需要扩展功能的原函数作为参数传递进去执行

def print_current_time(func):  #func为需要扩展增加时间戳功能的函数名
    print(time.time())
    func()

#那么对于f2,需要扩展功能,则如下实现
print_current_time(f2)

#但对于上述解决方案,扩展功能单独设置,没有与原函数整合
#本质上,上述print_current_time()函数的实现和下面代码一样
#print(time.time())
#f2()
#那么如何更好地作为原函数的扩展功能,则引入了装饰器这个概念

二、装饰器

import time

#装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名
def decorator(func):
    def wrapper():
        print(time.time())
        func()
    return wrapper


def f1():
    print("This is the f1 function.")

f = decorator(f1)
f()

对于上述代码,实现了装饰器的代码,但也并未直接将扩展功能和原始函数绑定关联

仍然需要通过f = decorator(f1)这样的代码去捆绑实现

python中通过@装饰器名实现关联

import time

#装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名
def decorator(func):
    def wrapper():
        print(time.time())
        func()
    return wrapper

@decorator
def f1():
    print("This is the f1 function.")

f1()     #等同于f = decorator(f1)     f()

 上述示例中f1()函数是没有参数的,如果带有参数,那么装饰器需要做哪些改动呢?

一个参数的情况:

import time
#一个参数的情况
#装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名
def decorator(func):
    def wrapper(fn):
        print(time.time())
        func(fn)
    return wrapper

@decorator
def f1(func_name):
    print("This is the f1 function named " + func_name)

f1("test func")  #等同于f2 = decorator(f1)   f2("test func")

对于同一装饰器,各类参数数量不一的函数都需要用到,则需要用可变参数去实现:

import time
#一个参数的情况
#装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名
def decorator(func):
    def wrapper(*args):
        print(time.time())
        func(*args)
    return wrapper

@decorator
def f1(func_name):
    print("This is the f1 function named " + func_name)

@decorator
def f2(a, b):
    print("a + b = " + str(a+b))
    print("This is the f2 function!")

f1("TEST FUNC")
f2(30, 50)

进一步如果涉及到关键字可变参数,则如下:

import time
#一个参数的情况
#装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名
def decorator(func):
    def wrapper(*args, **kw):
        print(time.time())
        func(*args, **kw)
    return wrapper

@decorator
def f1(func_name):
    print("This is the f1 function named " + func_name)

@decorator
def f2(a, b):
    print("a + b = " + str(a+b))
    print("This is the f2 function!")

@decorator
def f3(func_name1, func_name2, **kw):
    print("This is the f3 function " + func_name1)
    print("This is the f3 function " + func_name2)
    for k, v in kw.items():
        print(k, ":", v)

f1("func1 name")
f2(12, 38)
f3("test func1", "test func2", a = 1, b = 2, c = "ABC")

 

posted @ 2025-08-17 12:09  tsembrace  阅读(6)  评论(0)    收藏  举报