python中的无参装饰器和有参装饰器

                                       作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。


装饰器特点:    1>.开放封闭原则,即对扩展是开放的,对修改时封闭的;    2>.装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象;    3>.装饰器的功能是在不修改被装饰器对象源代码以及被装饰器对象的调用方式的前提下为其扩展新功能;    4>.装饰器本质是函数,(即装饰其他函数)就是为其他函数添加附加功能。

一.典型装饰器案例
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7 #装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字
 8 import time
 9 import random
10
11 def RunTime(TheCaller):  #定义装饰器
12     def MyCaller():
13         start_time = time.time()
14         TheCaller()
15         stop_time=time.time()
16         print('run time is %s' %(stop_time-start_time))
17     return MyCaller
18
19 #被装饰函数
20 @RunTime #等效于index=RunTime(index)
21 def index():
22     time.sleep(random.randrange(2,4))   #可以在1-3秒钟(不包括4秒哟)随机睡眠指定范围的时长。
23     print('welecome to INDEX page')
24
25 @RunTime #home=RunTime(home)
26 def home():
27     time.sleep(random.randrange(1,2))
28     print('welecome to HOME page')
29
30 index() #MyCaller()
31 home()
32
33
34
35
36 #以上代码执行结果如下:
37 welecome to INDEX page
38 run time is 2.0000088214874268
39 welecome to HOME page
40 run time is 1.0006351470947266

二.多个装饰器案例展示
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7 #装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字
 8 import time
 9 import random
10 from functools import wraps
11
12 def RunTime(TheCaller):  #定义装饰器+
13     @wraps(TheCaller)       #可以让用户查看帮助信息的时候查看其自己的源代码定义的帮助信息。
14     def MyCaller(*args,**kwargs):
15         '''
16         Runtime's help information
17         '''
18         start_time = time.time()
19         res = TheCaller(*args,**kwargs)
20         stop_time=time.time()
21         print('run time is %s' %(stop_time-start_time))
22         return res
23
24     return MyCaller
25
26 def NewAddAuth(TheCaller):
27     def Auth(*args,**kwargs):
28         name=input('username: ')
29         password=input('password: ')
30         if name == 'yinzhengjie' and password == '123':
31             print('login successful')
32             res = TheCaller(*args,**kwargs)
33             return res
34         else:
35             print('login error')
36     return Auth
37
38 #被装饰函数
39 # @NewAddAuth
40 @RunTime #等效于index=RunTime(index),装饰器的执行顺序是自下而上。
41 def Index():
42     '''
43     Index's help information
44     '''
45     time.sleep(random.randrange(2,4))   #可以在1-3秒钟(不包括4秒哟)随机睡眠指定范围的时长。
46     print('welecome to INDEX page')
47     return "yinzhengjie"
48
49 @RunTime #home=RunTime(home)
50 def Home(name):
51     '''
52       Home's help information
53       '''
54     time.sleep(random.randrange(1,2))
55     print('welecome to %s HOME page'%(name))
56     return 666
57
58 res1 = Index() #MyCaller()
59 res2 = Home("尹正杰")
60 print("Index return :%s"%(res1))
61 print("Home return :%s"%(res2))
62 # print(help(Index))
63 # print(Index().__doc__)
64
65
66
67
68 #以上代码执行结果如下:
69 welecome to INDEX page
70 run time is 3.000018835067749
71 welecome to 尹正杰 HOME page
72 run time is 1.0001890659332275
73 Index return :yinzhengjie
74 Home return :666

三.有参装饰器

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7 '''
 8 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登陆成功一次,后续的函数都无需再验证。
 9 '''
10
11
12 # user_dic = {13 #     'yinzhengjie':'123',
14 #     'Golang':"666",
15 #     'Python':"888",
16 # }
17 #
18 # with open("user.db","w",encoding="utf-8")as f:
19 #     f.write(str(user_dic))
20
21
22
23
24 db_path = "user.db"
25
26 login_dic ={
27     'user':None,
28     "status":False,
29 }
30
31 def Decorator(AuthType="file"):
32     def auth(func):
33         def wrapper(*args, **kwargs):
34             if AuthType == "file":
35                 if login_dic['user'] and login_dic['status']:
36                     res = func(*args, **kwargs)
37                     return res
38                 username = input("username:")
39                 password = input("password:")
40                 with open(db_path, "r", encoding="utf-8")as f:
41                     user_dic = eval(f.read())
42                 if username in user_dic and password == user_dic[username]:
43                     print('login successful')
44                     login_dic['user'] = username
45                     login_dic['status'] = True
46                     res = func(*args, **kwargs)
47                     return res
48                 else:
49                     print('login error')
50             elif AuthType == "ldap":
51                 print("LDAP认证方式")
52             elif AuthType == "MySQL":
53                 print("MySQL认证方式")
54             else:
55                 print("其他认证方式")
56         return wrapper
57     return auth
58
59 @Decorator()
60 def Index():
61     print("Welcome to Index!")
62
63 @Decorator(AuthType="MySQL")
64 def home(name):
65     print("Welecome %s to home page!"%name)
66
67 Index()
68 home("尹正杰")
69
70
71
72
73 #以上代码执行结果如下:
74 username:yinzhengjie
75 password:123
76 login successful
77 Welcome to Index!
78 MySQL认证方式

四.小试牛刀1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登陆成功一次,后续的函数都无需再验证。
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7
 8 # user_dic = { 9 #     'yinzhengjie':'123',
10 #     'Golang':"666",
11 #     'Python':"888",
12 # }
13 #
14 # with open("user.db","w",encoding="utf-8")as f:
15 #     f.write(str(user_dic))
16
17
18
19
20 db_path = "user.db"
21
22 login_dic ={
23     'user':None,
24     "status":False,
25 }
26
27 def auth(func):
28     def wrapper(*args,**kwargs):
29         if login_dic['user'] and login_dic['status']:
30             res = func(*args, **kwargs)
31             return res
32         username = input("username:")
33         password = input("password:")
34         with open(db_path, "r", encoding="utf-8")as f:
35             user_dic = eval(f.read())
36         if username in user_dic and password == user_dic[username]:
37             print('login successful')
38             login_dic['user'] = username
39             login_dic['status'] = True
40             res = func(*args,**kwargs)
41             return res
42         else:
43             print('login error')
44     return wrapper
45
46 @auth
47 def Index():
48     print("Welcome to Index!")
49
50 @auth
51 def home(name):
52     print("Welecome %s to home page!"%name)
53
54 Index()
55 home("尹正杰")
56
57
58
59
60 以上代码执行结果如下:
61 username:yinzhengjie
62 password:123
63 login successful
64 Welcome to Index!
65 Welecome 尹正杰 to home page!

2.编写下载网页内容的函数,要求功能是:用户传入一个URL,函数返回下载页面的内容。

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7
 8 from urllib.request import urlopen
 9 import os
10
11 cache_path=r'cache.txt'
12 def make_cache(func):
13     def wrapper(*args,**kwargs):
14         if os.path.getsize(cache_path):#说明有缓存
15             print('\033[45m=========有缓存=========\033[0m')
16             with open(cache_path,'rb') as f:
17                 res=f.read()
18
19         else:
20             res=func(*args,**kwargs) #下载
21             with open(cache_path,'wb') as f: #制作缓存
22                 f.write(res)
23
24         return res
25
26     return wrapper
27
28 @make_cache
29 def get(url):
30     return urlopen(url).read()
31
32
33 print('============first============')
34 print(get('http://www.cnblogs.com/yinzhengjie'))
35 print('============second===========')
36 print(get('http://www.cnblogs.com/yinzhengjie'))
37 print('============third============')
38 print(get('http://www.cnblogs.com/yinzhengjie'))

3.装饰器包装原函数案例

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6
 7 FuncDict={}
 8
 9 def MakeDict(key):
10     def deco(func):
11         FuncDict[key]=func
12         # def wrapper(*args,**kwargs):          #此行及以下3行可以不写,这样就可以达到隐藏你原来函数的名字。
13         #     res = func(*args,**kwargs)
14         #     return res
15         # return wrapper
16     return deco
17
18
19 @MakeDict("one")
20 def First():
21     print("From Shell")
22
23
24 @MakeDict("two")
25 def Second():
26     print("From Second")
27
28 @MakeDict("three")
29 def Third():
30     print("From Third")
31
32 print(FuncDict)
33
34 while True:
35     cmd = input(">>>:").strip()
36     if  cmd in FuncDict:
37         FuncDict[cmd]()
38
39
40
41 #以上代码执行结果如下:
42 {'one': <function First at 0x027E38E8>, 'two': <function Second at 0x027E3810>, 'three': <function Third at 0x027E38A0>}
43 >>>:three
44 From Third
45 >>>:one
46 From Shell
47 >>>:two
48 From Second
49 >>>:
50 >>>:
51 >>>:

 

转载于:https://www.cnblogs.com/yinzhengjie/p/8467930.html

python中的无参装饰器和有参装饰器相关推荐

  1. python作用域的理解-python中对变量的作用域LEGB、闭包、装饰器基本理解

    一.作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量 ...

  2. 在Python中的无参装饰器和有参装饰器

    装饰器特点: 1.开放封闭原则,即对扩展是开放的,对修改时封闭的: 2.装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象: 3.装饰器的功能是在不修改被装饰器对象源代码以及被装饰器 ...

  3. python中编写无参数decorator

    Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = de ...

  4. 处理python中的无类型变量的方法

    1 可以用isinstance(obj, class)来判断 转载于:https://www.cnblogs.com/hustdc/p/7131957.html

  5. python编写装饰器_写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) 1 de ...

  6. python高级语法装饰器_Python高级编程——装饰器Decorator超详细讲解上

    Python高级编程--装饰器Decorator超详细讲解(上篇) 送你小心心记得关注我哦!! 进入正文 全文摘要 装饰器decorator,是python语言的重要特性,我们平时都会遇到,无论是面向 ...

  7. 在Python中什么是闭包?能做什么?

    1.什么是闭包 当我们在外部函数中定义了一个内部函数,并且内部函数能够读取到外部函数内的变量,这种函数我们就称为闭包.简单来说,闭包就是能够读取外部函数内的变量的函数.闭包的架子大概是这样: def ...

  8. python里面的之前打过的记忆信息-python中的记忆:如何缓存函数的运行结果(1)

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 使用称为"memoization"的强大而方便的缓存技术来加速您的Python程序. ...

  9. python有什么作用-Python中的闭包到底有什么用

    1.global关键字的作用 如果在函数中需要修改全局变量,则需要使用该关键字,具体参见下面例子. variable=100 deffunction():print(variable) #在函数内不对 ...

最新文章

  1. KOAProgressBar
  2. Throwable是java.lang包中一个专门用来处理异常的类
  3. mysql数据库帐户_MySQL数据库用户帐号管理基础知识详解
  4. 复现经典:《统计学习方法》第 8 章 提升方法
  5. android P精简教程,华为EMUI 9.0发布:基于Android P打造 设置项精简10%
  6. Nginx Rewrite规则初探
  7. java手机号判断运营商_用Java对手机号所属运营商进行判断
  8. 补丁 检测系统_大云制造 | BCLinux For ARM64 V7.6操作系统正式发布
  9. 容器编排技术 -- Kubernetes kubectl 与 Docker 命令关系
  10. Android 6.0谷歌卡刷包,卡刷包走起:谷歌Nexus5升级安卓6.0/Android M教程
  11. 凯恩帝数控系统面板介绍_KND凯恩帝数控系统说明书
  12. 简单易用的运动控制卡(八):直线插补和手轮运动
  13. Fisher判别分析详解
  14. 计算机画大熊猫教案,大班美术画大熊猫教案
  15. Git版本管理工具使用知识汇总
  16. 人称代词的各种形式与用法
  17. 2022 ICPC Gran Premio de Mexico 1ra Fecha(一)
  18. C语言:小写字母与大写字母的转换
  19. C或C++中的isalpha、isalnum、islower 和 isupper函数的详解
  20. 【特征检测】BRISK特征提取算法

热门文章

  1. 《MATLAB图像处理375例》——1.8 MATLAB程序流程控制结构
  2. 记录从前端到后端--博客项目
  3. 使用sublime text 开发node.js
  4. 命令行下载利器- Aria2
  5. keras_14_初始化Initializers
  6. 【DRF框架】序列化组件——字段验证
  7. 必做作业2:目前比较火的直播软件调研
  8. Unit05: window 常用子对象-2 、 event 对象 、 Cookie
  9. table列宽控制,word-break等
  10. Sql server profiler抓出的语句不可信