Python装饰器原理与用法分析


本文摘自php中文网,作者不言,侵删。

这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下

本文实例讲述了Python装饰器原理与用法。分享给大家供大家参考,具体如下:

1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能

2、装饰器的原则:

(1) 装饰器不能修改被装饰的函数的源代码

(2) 装饰器不能修改被装饰的函数的调用方式

3、实现装饰器的知识储备

(1) Python中函数即‘变量'

a、变量在Python中的存储

1

2

x='Tomwenxing'

y=x

[说明]:

当Python解释器遇到语句x='Tomwenxing'时,它主要完成了两样工作:

  1.在内存中开辟了一片空间用来存储字符串‘Tomwenxing'

  2.在内存从创建了一个名为x的变量,并用它指向字符串‘Tomwenxing'所占据的内存空间(可以理解为房间和房间号的关系)

而语句y=x意为将变量x对字符串的引用赋值给变量y,即在内存中创建一个变量y,并使其指向变量x所指向的内存空间

b、函数在Python中的存储

1

2

def test():

  pass

[说明]:

在Python中,函数的存储和变量相似,以上面的函数为例,Python解释其主要做两件事:

  1.在内存中开辟一个内存空间,用来存储函数代码的字符串(本例中代码只有一句:pass)

  2.在内存中创建一个变量test,用来指向存储函数代码字符串的内存空间(相当于test=‘函数体')

因此说在Python中函数即变量

(2) 高阶函数(下面两个条件满足任何一个即为高阶函数)

a、把一个函数名当做实参传递给另外一个函数

[对装饰器的影响]:达到“在不修改被装饰函数源代码的情况下为其添加功能”的效果

1

2

3

4

5

6

7

8

9

10

import time

def bar():

  time.sleep(2)

  print('in the bar')

def test(func):

  start_time=time.time()

  func()

  stop_time=time.time()

  print('函数的运行时间为:',stop_time-start_time)

test(bar)

运行结果:

in the bar
函数的运行时间为: 2.0021145343780518

b、返回值中包含函数名

[对装饰器的影响]:达到“不改变函数的调用方式“的效果

1

2

3

4

5

6

7

8

9

import time

def bar():

  time.sleep(3)

  print('in the bar')

def test2(func):

  print('新添加的功能')

  return func

bar=test2(bar)

bar()

运行结果:

新添加的功能
in the bar

(3) 嵌套函数:在一个函数体内用def去声明一个新的函数(不是调用)

1

2

3

4

5

6

def foo():

  print('in the foo')

  def bar(): #声明一个新的函数,而不是调用函数

    print('in the bar')

  bar()

foo()

运行结果:

in the foo
in the bar

4、装饰器的语法:高阶函数+嵌套函数=》装饰器 (下面的例子可以用pycharm的调试器调试一下,看看代码的运行顺序)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import time

def timer(func):

  def deco(*args,**kwargs):#使用了不定参数

    start_time=time.time()

    res=func(*args,**kwargs) #运行函数

    stop_time=time.time()

    print('运行时间:',stop_time-start_time)

    return res # 若无返回值,则返回None

  return deco

@timer #等价于test1=timer(test1)=deco,即test1()=deco()

def test1():

  time.sleep(3)

  print('in the test1')

@timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)

def test2(name):

  time.sleep(3)

  print('in the test2',name)

test1()

print('-------------分界线------------------------')

test2('Tomwenxing')

运行结果:

in the test1
运行时间: 3.0001718997955322
-------------分界线------------------------
in the test2 Tomwenxing
运行时间: 3.000171422958374

5、带参数的装饰器

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

# -*- coding:utf-8 -*-

user,passwd='Tomwenxing','123'

#如装饰器带参数,一般是三层嵌套

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('用户Tomwenxing已经成功登录!')

          res = func(*args, **kwargs) #运行目标函数

          return res

        else:

          exit('用户名或密码有错误')

      elif auth_type=='ldap':

        print('暂不支持这种登录方式!')

    return wrapper

  return outer_wrapper

def index():

  print('欢迎来到index页面')

@auth(auth_type='local') #home=wrapper()

def home(name):

  print('%s,欢迎来到home页面' %name)

  return 'This is home page'

@auth(auth_type='ldap')

def bbs():

  print('欢迎来到bbs页面 ')

index()

print('----------------------分界线-------------------')

print('函数的返回值为:',home('wenxing'))

print('----------------------分界线-------------------')

bbs()

运行结果:

欢迎来到index页面
----------------------分界线-------------------
Username:Tomwenxing
Password:123
用户Tomwenxing已经成功登录!
wenxing,欢迎来到home页面
函数的返回值为: This is home page
----------------------分界线-------------------
暂不支持这种登录方式!

相关推荐:

使用python装饰器计算函数运行时间

Python迭代器定义与简单用法分析

以上就是Python装饰器原理与用法分析的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python基础操作汇总

Python中eval函数怎么用

简述Python如何调用系统底层api播放wav文件

Python什么是递归?两种优先搜索算法的实现 (代码示例)

microPython选哪个好?

Python统计不同字符的个数

方法示例Python如何把字典写入到csv文件的

Python中导入模块中的对象有哪几种方式

Python如何遍历字符串

Python如何切换线程

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...