python基础——装饰器

本文详细介绍了Python中装饰器的概念及其工作原理,包括如何使用装饰器来增强函数功能而不修改其源代码,同时展示了不同场景下装饰器的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

装饰器:本质是函数,(装饰其他函数)就是为其他函数添加附加功能。
装饰器用途:在不修改原函数源代码和调用方式的情况下,为原函数添加新的功能。
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
高阶函数+嵌套函数=》装饰器

举例
这种不能传递参数,不是通用型,通俗的说就是在函数外套一个函数,把原函数当做参数传递进去,并在里头调用加上要实现的功能,最后返回内层函数的地址。

import time
#装饰器
def timer(func):#外层函数,func是形参,把原函数的地址传递进来
    def deco():
        start_time=time.time()#实现的新功能
        func()#地址加了括号就是调用,即调用原函数
        stop_time=time.time()#实现的新功能
        print("the func run time is ,(stop_time-start_time))"#实现的新功能
    return deco#返回内层函数的地址
@timer #test1=timer(test1),必须要有这个,这个其实就是test1=deco
def test1():
    time.sleep(3)
    print("int the test1")
test1()#test1()=deco(),做了一个转换,之所以这样做的原因是deco()不能直接用,它是一个局部函数

通用型,可以传递任意个参数,应用场景:有些函数需要添加相同的功能,但是它们当中有些需要传递参数进去(不同的原函数有不同的功能,但它们添加的新功能相同),有些不需要,这个时候就需要实现能兼容传递参数和不传递参数的装饰器,下面的例子就是这样的一个通用型装饰器。

import time
def timer(func):
    def deco(*args,**kwargs):#注意这里需要传递参数
        start_time=time.time()
        func(*args,**kwargs)#注意这里需要传递参数
        stop_time=time.time()
        print("the total time is:",(stop_time-start_time))
    return deco
@timer# @timer要紧挨着被装饰函数的上方
def test1():
    time.sleep(3)
    print("int the test1")
@timer
def test2(name,age):#这个原函数需要传递参数
    time.sleep(3)
    print("test2:",name,age)
test1()
test2("Jorocco",23)

这种情况是装饰器带有参数,当我们的外层函数有参数的时候,此时需要在外面再加一层


import time
user,passwd="Jorocco","123ab"
def auth(auth_type):
   def outer_wrapper(func):
        def wrapper(*args,**kwargs):
            if auth_type=="local":
                username=input("Username:").strip()
                password=input("Password:").strip()
                if user==username and passwd==password:
                    print("\033[32;1mUser has passed authentication\033[0m")
                    res=func(*args,**kwargs)#1号位置,有返回值,就需要有这个
                    print("---after authenticaion")
                    return res#1号位置,有返回值,就需要有这个,不然就没有1号位置的返回结果
                else:
                    exit("\033[31;1mInvalid usrname or password\033[0m")
            elif auth_type=="ldap":
                print("gameover")
        return wrapper
   return outer_wrapper

def index():
    print("welcome to index")
@auth(auth_type="local")#auth_type="local"有这个参数
def home():
    print("welcome to home")
    return 3# 1号位置,有返回值
@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs")

index()
print(home())
bbs()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值