Python 学习笔记 - 装饰器

简介:

这一节了解了一些装饰器的简单使用。


首先来看一个预备知识,把一个函数当做参数,传入另外一个函数

比如说我传递outer(f1),我传入的是f1的内存地址,a=func()其实执行了f1()这个函数,并把返回值赋给了a,因此当我打印print(a),他会输出hee

1
2
3
4
5
6
7
8
9
10
11
12
>>>  def  outer(func):
     print (func)
     a = func()
     print (a)
def  f1():
     print ( "aaa" )
     return  "hee"
outer(f1)
- - - - - - - - - - - -
<function f1 at  0x0000023D3FF3D510 >
aaa
hee

装饰器(decorator)就是利用可以把函数当做传递这一点,他可以统一给一些函数添加一些“修饰”功能,但是又不会去破坏原有的代码。装饰器本身也是一个函数,其他函数调用他的时候,在其他函数前面 @ +装饰器名的格式就行了


 这个格式执行了2个功能:

     1. 自动执行装饰器函数并且将其下面的函数名f1当作参数传递

     2. 将装饰器函数的返回值,重复赋值给 f1

简单的说就是这样

f1=decortor(f1)


把上面的例子稍微修改成装饰器,如下所示,结果是一样的

1
2
3
4
5
6
7
8
9
10
11
12
def  outer(func):
     def  innner( * args, * * kwargs):
         print (func)
         a = func( * args, * * kwargs)
         print (a)
         return  a
     return  innner
@outer
def  f1():
     print ( "aaa" )
     return  "hee"
f1()



再看另外一个复杂一些的例子:

我定义了3个函数f1,f2,f3,他们有不同的参数,我需要每个函数在现在的结果前面添加一个'before',结果后面添加一个‘after’


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def  outer(func):
     def  inner( * args,  * * kwargs):
         print ( 'before' )
         =  func( * args,  * * kwargs)
         print ( 'after' )
         return  r
     return  inner
 
@outer
def  f1(arg):
     print (arg)
     return  "F1"
     
@outer
def  f2(a1, a2):
     print ( "F2" )
     
@outer
def  f3():
     print ( "F3" )
     
     
f1( "hhh" )
f2( "bbb" , 444 )
f3()


结果如下:

1
2
3
4
5
6
7
8
9
before
hhh
after
before
F2
after
before
F3
after


注意要点:

  1. 当使用装饰器outer的时候,他传递参数 outer(f1),这里传递的是f1的地址;r=func()其实执行的就是f1(),然后把返回值赋给了r,这里的目的是为了保证inner返回的结果和f1返回的结果一样;最后再把装饰过的inner函数地址赋给f1,实现装饰的效果;

  2. 记得前面的万能参数 f(*args,**kwargs),可以接受任意的参数


例2:装饰器一个广泛使用的场景是登录验证;很多功能必须判断登录之后才能使用。

下面的例子装饰器通过一个全局变量LOGIN_USER来判断是否已经登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
LOGIN_USER  =  { "is_login" False  }
def  outer(func):
     def  inner( * args,  * * kwargs):
         if  LOGIN_USER[ 'is_login' ]:
             =  func()
             return  r
         else :
             print ( "请登录" )
     return  inner
def  outer1(func):
     def  inner( * args,  * * kwargs):
         if  LOGIN_USER[ 'is_login' and  LOGIN_USER[ 'user_type' = =  2 :
             =  func()
             return  r
         else :
             print ( "请登录,或者权限不够" )
     return  inner
@outer1
def  order():
     print ( "欢迎%s登录"  %  LOGIN_USER[ 'current_user' ])
@outer
def  changepwd():
     print ( "欢迎%s登录"  %  LOGIN_USER[ 'current_user' ])
@outer
def  manager():
     print ( "欢迎%s登录"  %  LOGIN_USER[ 'current_user' ])
def  login(user, pwd):
     if  user  = =  "alex"  and  pwd  = =  "123" :
         LOGIN_USER[ 'is_login' =  True
         LOGIN_USER[ 'current_user' =  user
         manager()
def  main():
     while  True :
         inp  =  input ( "1,后台管理;2,登录" )
         if  inp  = =  '1' :
             manager()
         elif  inp  = =  '2' :
             username  =  input ( "请输入用户名" )
             pwd  =  input ( "请输入密码" )
             login(username, pwd)
main()


例3.

如果有多个装饰器,我可以嵌套的使用,因为一层的装饰器之后其实也是一个函数,那他自然可以再继续被装饰。 


比如说,注意他的调用顺序是从下往上的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Python  3.5 . 2  (v3. 5.2 : 4def2a2901a5 , Jun  25  2016 22 : 18 : 55 ) [MSC v. 1900  64  bit (AMD64)] on win32
>>>  def  outer(func):
     def  innner( * args, * * kwargs):
         print (func)
         a = func( * args, * * kwargs)
         print ( "装饰1" )
         return  a
     return  innner
def  outer2(func):
     def  inner( * args, * * kwargs):
         print (func)
         a = func( * args, * * kwargs)
         print ( "装饰2" )
         return  a
     return  inner
@outer2
@outer
def  f1():
     print ( "原函数" )
     return  "hee"
f1()
<function outer.< locals >.innner at  0x000001FF89A6D620 >
<function f1 at  0x000001FF89A6D598 >
原函数
装饰 1
装饰 2


wKioL1fGfAvwfoMgAAB_lmOBgy0357.png






本文转自 beanxyz 51CTO博客,原文链接:http://blog.51cto.com/beanxyz/1844747,如需转载请自行联系原作者

目录
相关文章
|
7天前
|
开发者 Python
探索Python中的装饰器:从基础到高级应用
本文将带你深入了解Python中的装饰器,这一强大而灵活的工具。我们将一起探讨装饰器的基本概念,它们如何工作,以及如何使用它们来增强函数和类的功能,同时不改变其核心逻辑。通过具体代码示例,我们将展示装饰器的创建和使用,并探索一些高级应用,比如装饰器堆栈和装饰带参数的装饰器。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角,帮助你更有效地使用装饰器来简化和优化你的代码。
|
8天前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到高级应用
装饰器在Python中是一个强大且令人兴奋的功能,它允许开发者在不修改原有函数代码的前提下增加额外的功能。本文将通过具体代码示例,带领读者从装饰器的基础概念入手,逐步深入到高级用法,如带参数的装饰器和装饰器嵌套等。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
8天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
20 6
|
10天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
28 11
|
7天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
23 7
|
6天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
7天前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
30 6
|
6天前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
7天前
|
测试技术 开发者 Python
深入理解Python装饰器:从基础到高级应用
本文旨在为读者提供一个全面的Python装饰器指南,从其基本概念讲起,逐步深入探讨其高级应用。我们将通过实例解析装饰器的工作原理,并展示如何利用它们来增强函数功能、控制程序流程以及实现代码的模块化。无论你是Python初学者还是经验丰富的开发者,本文都将为你提供宝贵的见解和实用的技巧,帮助你更好地掌握这一强大的语言特性。
20 4
|
8天前
|
开发者 Python
Python中的装饰器:从入门到实践
本文将深入探讨Python的装饰器,这一强大工具允许开发者在不修改现有函数代码的情况下增加额外的功能。我们将通过实例学习如何创建和应用装饰器,并探索它们背后的原理和高级用法。
24 5