Python笔记:Python装饰器装饰器是通过装饰器函数修改原函数python装饰函数的一些功能而不需要修改原函数python装饰函数,在很多场景可以用到它python装饰函数,比如① 执行某个测试用例之前,判断是否需要登录或者执行某些特定操作python装饰函数;② 统计某个函数的执行时间;③ 判断输入合法性等 。合理使用装饰器可以极大地提高程序的可读性以及运行效率 。本文将介绍Python装饰器的使用方法 。
python装饰器可以定义如下:
输出:
python解释器将test_decorator函数作为参数传递给my_decorator函数 , 并指向python装饰函数了内部函数 wrapper(),内部函数 wrapper() 又会调用原函数 test_decorator(),所以decorator()的执行会先打印'this is wrapper',然后打印'hello world' , test_decorator()执行完成后,打印 'bye',*args和**kwargs,表示接受任意数量和类型的参数 。
装饰器 my_decorator() 把真正需要执行的函数 test_decorator() 包裹在其中,并且改变了它的行为,但是原函数 test_decorator() 不变 。
一般使用如下形式使用装饰器:
@my_decorator就相当于decorator = my_decorator(test_decorator)语句 。
内置装饰器@functools.wrap可用于保留原函数的元信息(将原函数的元信息 , 拷贝到对应的装饰器函数里) 。先来看看没有使用functools的情况:
输出:
从上面的输出可以看出test_decorator() 函数被装饰以后元信息被wrapper() 函数取代了 , 可以使用@functools.wrap装饰器保留原函数的元信息:
输出:
装饰器可以接受自定义参数 。比如定义一个参数来设置装饰器内部函数的执行次数:
输出:
Python 支持多个装饰器嵌套:
装饰的过程:
顺序从里到外:
test_decorator('hello world') 执行顺序和装饰的过程相反 。
输出:
类也可以作为装饰器,类装饰器主要依赖__call__()方法 , 是python中所有能被调用的对象具有的内置方法(python魔术方法),每当调用一个类的实例时,__call__()就会被执行一次 。
下面的类装饰器实现统计函数执行次数:
输出:
下面介绍两种装饰器使用场景
统计函数执行所花费的时间
输出:
在使用某些web服务时,需要先判断用户是否登录,如果没有登录就跳转到登录页面或者提示用户登录:
--THE END--
什么是Python装饰器装饰器(decorator)是Python中的高级语法 。装饰的意思就是动态扩展被装饰对象的功能 。装饰器可以用于装饰函数、方法和类 。
一 嵌套函数
# 定义一个外层函数def foo(): # 定义了一个内部函数 def bar(): print("hello world")
函数bar是一个定义在foo函数内部的函数 。
Python中的函数是支持嵌套的 , 也就是可以在一个函数内部再定义一个函数 。
然后,我们还知道函数是可以当作变量的,于是我们就可以在foo函数中把定义的这个bar函数返回 。就像下面这样:
# 定义一个外层函数def foo(): # 定义了一个内层函数 def bar(): print("hello world") return
barfunc = foo()func() # func -- bar,这里执行func其实就相当于执行了在foo函数内部定义的bar函数
二 闭包形态1
# 闭包形态1def foo(): name = "Andy" # 外部函数的局部变量 # 定义了一个内部函数 def bar():
print(name) # 虽然bar函数中没有定义name变量,但是它可以访问外部函数的局部变量name return barfunc =
foo()func() # func -- bar -- 除了是一个函数 , 还包含一个值(它外层函数的局部变量)的引用
三 闭包形态2
# 闭包形态2def foo(name): # 给一个函数传参也相当于给函数定义了一个局部变量 # 定义了一个内部函数 def bar():
print(name) # 内部函数同样可以获取到传到外部函数的变量(参数) return barfunc = foo("Andy") #
把“Andy”当成参数传入foo函数 -- 其内部定义的bar函数也能拿到这个“Andy”func() # func -- bar --
除了是一个函数,还包含一个值(它外层函数的参数)的引用
四 装饰器形态1
# 还是定义一个外层函数def foo(name): # 我接收的参数是一个函数名 # 定义了一个内部函数 def bar():
print("这是新功能 。。。") # 新功能 name() # 函数名加()就相当于执行-- 我传进来原函数的函数名,这里就相当于执行了原函数
return bar# 定义一个被装饰的函数def f1(): print("hello world.") # 用foo函数装饰f1函数f1 =
foo(f1)# 不改变f1的调用方式f1() # -- 此时函数已经扩展了新功能
五 装饰器形态2
# 还是定义一个外层函数def foo(name): # 接收的参数是一个函数名 # 定义了一个内部函数 def bar():
print("这是新功能 。。。") # 新功能 name() # 函数名加()就相当于执行-- 传进来原函数的函数名,这里就相当于执行了原函数
return bar# 定义一个被装饰的函数# 用foo函数装饰f1函数@foo # 使用f1 =
foo(f1)语法装饰的话稍显啰嗦,Python就提供了@语法,让装饰过程更简便def f1(): print("hello world.") #
不改变f1的调用方式f1() # -- 此时函数已经扩展了新功能 。
python装饰器使用 装饰器是从英文decorator翻译过来的,从字面上来看就是对某个东西进行修饰,增强被修饰物的功能,下面我们对装饰器做下简单介绍 。
一、怎么编写装饰器
装饰器的实现很简单 , 本质是一个可调用对象,可以是函数、方法、对象等,它既可以装饰函数也可以装饰类和方法,为了简单说明问题 , 我们实现一个函数装饰器,如下代码:
有了这个装饰器,我们就可以打印出什么时候开始和结束调用函数,对于排查函数的调用链非常方便 。
二、带参数的装饰器
上面的例子无论什么时候调用sum都会输出信息,如果我们需要按需输出信息怎么实现呢,这时就要用到带参数的装饰器了,如下代码:
对sum使用装饰器时没有参数,这时debug为0,所以调用sum时不会输出函数调用相关信息 。
对multi使用装饰器时有参数,这时debug为1 , 所以调用multi时会输出函数调用相关信息 。
三、函数名字问题
当我们打印被装饰后的函数名字时,不知道大家有没发现输出的不是函数本身的名字,如下代码会输出‘wrap’而不是‘sum’:
有时这种表现并不是我们想要的,我们希望被装饰后的函数名字还是函数本身,那要怎么实现呢?很简单,只需要引入functools.wraps即可,如下代码就会输出‘sum’了:
看完后是不是觉得python装饰器很简单,只要了解它的本质,怎么写都行,有好多种玩法呢 。
【关于python装饰函数的信息】关于python装饰函数和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。
推荐阅读
- php读取808协议数据,php读取写入文件
- jquerydatatable读取数据,jquery datatable api中文文档
- 怎么注销美团公众号,美团账号怎样注销
- 日系模拟男友手机游戏下载,模拟男友小游戏
- php数据格式验证 php如何实现验证码功能
- 苹果iOS16跳电,废都物语拉邦装备
- 幽灵键鼠虚拟机使用教程,幽灵键鼠怎么自己编程
- 直播卖货6.18预告,直播卖货技巧和话术
- php提交多个数据库 php连接多个数据库