04-python 学习第四点-装饰器
装饰器就是一个函数,他是通过不修改某个函数的源代码和调用方式的前提下可以添加新功能的一种函数。在python 中装饰器一般采用高阶函数和嵌套函数达到装饰的作用,下面进行实例讲解:
1、目前有一个网址有很多页面(比如:index,home,bbs)。因为时老文字,所有页面都是可以直接浏览的。实现效果如下:
def home():#模拟网页homne
print("wolcome to home") def bbs():#模拟网页bbs
print("wolcome to bbs") index() #调用index
home() #调用home
bbs() #调用bbs
运行结果如下:各个网站均可以直接浏览
wolcome to index
wolcome to home
wolcome to bbs
2、公司有了新规定要求主页indezx 保留原始状态直接浏览,home 和bbs 需要登录才能浏览,不允许修改目前的函数源代码和调用方式实现这个功能。这下则么办呢?
我们可以为需要登录才能浏览的网页home 和bbs 函数进行装饰即可。
user, passwd = 'dwdar', 'abc123' # 模拟用户名密码数据库 def auth(func): # 登录装饰器
def wrapper():
username = input("UserName:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("登录成功")
func()
else:
exit("验证失败!") return wrapper def index():
print("wolcome to index") @auth # home 被装饰(没有修改源代码和调用方式)
def home():
print("wolcome to home") @auth # bbs被装饰(没有修改源代码和调用方式)
def bbs():
print("wolcome to bbs") index()
bbs()
home()
运行结果:
index 直接可以显示
wolcome to index
随后要求输入用户名和密码,登录后才能浏览home 和bbs
UserName:dwdar
Password:abc123
登录成功
wolcome to bbs
UserName:dwdar
Password:abc123
登录成功
wolcome to home
3、通过几年的发展,网站又有了新的要求,home 这个函数需要返回值了,需要我们更新以下装饰器。
假设home的返回值是这样的。
@auth # home 被装饰(没有修改源代码和调用方式)
def home():
print("wolcome to home")
return "from home" #home 需要返回值
目前的装饰器是无法实现返回值的,我们对装饰器进行如下升级即可打印返回值了。
# Author:Dwdar user, passwd = 'dwdar', 'abc123' # 模拟用户名密码数据库 def auth(func): # 登录装饰器
def wrapper(*args,**kwargs):
username = input("UserName:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("登录成功")
res = func(*args,**kwargs)
return res
else:
exit("验证失败!") return wrapper def index():
print("wolcome to index") @auth # home 被装饰(没有修改源代码和调用方式)
def home():
print("wolcome to home")
return "from home" # home 需要返回值 @auth # bbs被装饰(没有修改源代码和调用方式)
def bbs():
print("wolcome to bbs") index()
bbs()
print(home()) #打印home的返回值
4、又过了一段时间,网站又有了新变化,要求BB 用本地认证系统登录,而BBS需要ldap 认证服务器登录。这下怎么办呢?
第一步:首选我们想到调用装饰器需要传参,通过装饰器参数来判断调用方式。调用装饰器如下。
def index():
print("wolcome to index") @auth(auth_type="local") # 装饰器需要传参,通过参数判断登录方式
def home():
print("wolcome to home")
return "from home" @auth(auth_type="ldap") # 装饰器需要传参,通过参数判断登录方式
def bbs():
print("wolcome to bbs")
第二步:装饰器再添加一层函数 outer_wrappr 来接收相关参数最终可以实现判断。
完整代码如下:
# Author:Dwdar
'''
有一个网址有多个页面,大部分页面时直接浏览的。比如index
后来有了新的要求:
要对home 和页面BBS页面登录才能预览。通过装饰器需要给home 和BBS 添加登录的功能怎么做呢? ''' user, passwd = 'dwdar', 'abc123'
bbsuser, bbspasswd = 'bbs', 'bbs123' # 模拟ldap 认证账号 def auth(auth_type):
# print("auth func:", auth_type) def outer_wrappr(func):
def wrapper(*args, **kwargs):
# print("wrapper func arges:", *args, **kwargs)
if auth_type == "local":
username = input("UserName:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("登录成功")
res = func(*args, **kwargs)
return res
else:
exit("验证失败!")
elif auth_type == "ldap":
username = input("bbsUserName:").strip()
password = input("bbsPassword:").strip()
if bbsuser == username and bbspasswd == password:
print("登录成功")
res = func(*args, **kwargs)
return res
else:
exit("BBS验证失败!") return wrapper return outer_wrappr def index():
print("wolcome to index") @auth(auth_type="local") # 装饰器需要传参,通过参数判断登录方式
def home():
print("wolcome to home")
return "from home" @auth(auth_type="ldap") # 装饰器需要传参,通过参数判断登录方式
def bbs():
print("wolcome to bbs") index()
bbs()
print(home())
运行结果:
wolcome to index
bbsUserName:bbs
bbsPassword:bbs123
登录成功
wolcome to bbs
UserName:
通过判断登录BBS需要输入用户名:BBS的账号和密码才能进入。
04-python 学习第四点-装饰器的更多相关文章
- Python学习笔记:装饰器
Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...
- Python学习笔记012——装饰器
1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...
- python学习之day5,装饰器,生成器,迭代器,json,pickle
1.装饰器 import os import time def auth(type): def timeer(func): def inner(*args,**kwargs): start = tim ...
- python学习笔记:装饰器2
python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...
- Python学习——迭代器&生成器&装饰器
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...
- 从零开始的Python学习Episode 11——装饰器
装饰器 装饰器是用来处理其他函数的函数,主要作用是在不修改原有函数的情况下添加新的功能,装饰器的返回值也是一个函数对象. 简单的装饰器 import time def show_time(f): de ...
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- Python学习系列之装饰器
装饰器的作用 装饰器用于装饰某个函数.方法或者类,它可以让这个函数执行之前或者执行之后做一些操作 手工实现一个装饰器 def outer(some_func): #装饰器 $1 def inner() ...
- Python学习日记(九) 装饰器函数
1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...
- Python 学习 —— 进阶篇(装饰器、类的特殊方法)
Python基础部分学完之后,在进入其OOP部分前,先理解一下其装饰器这种结构,其功能可类比于Java中的面向切面编程,下面参见具体实例: def log(f): def fn(x): print ' ...
随机推荐
- 针对Java集合类的小总结
Java集合类包位于java.util下,有很多常用的数据结构:数组.链表.队列.栈.哈希表等等.了解不同的集合类的特性在开发过程中是比较重要的,感谢@兰亭风雨的专栏分析,这里我也根据自己的理解做轻度 ...
- 安装keepalived 出现configure: error: Popt libraries is required
keepalived执行./configure --prefix=/usr/local/keepalived时报错:configure: error: Popt libraries is requir ...
- MySQL基础知识 数据库 数据表
1.数据库结构 库 表 数据 2. sql(structured query language)结构化查询语言 管理数据库 管理表 管理数据 3.数据库 增删改查 增 create database ...
- Windows taskkill
TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM imag ...
- 关于CTreeView中CTreeCtrl空间的使用
昨天QQ群里有人问我怎么实现CTreeCtrl的功能,说实话,我也是一个VC 的初级学者,没有弄过CTreeView的代码,参考了MSDN后,写了一小段代码,和大家一起分享,其中包括窗口切分,都是比较 ...
- IDEA被删除的模块在编译时会再次出现
工程根目录下.idea文件->compiler.xml,删除多余的model,workspace.xml->删除带有无用的target标签
- hibernate_03_hibernate一对多的关系映射
1.实体类的一对多的关系映射 一个客户对应多个联系人 Customer.java public class Customer { private Long cust_id; private Strin ...
- 初学Servlet在IDEA中遇到的错误码问题
1.跳转页面出现500状态码 调试时出现如图所示报错: 需要进入Project Structure中进行如下操作: 点击Apply后导入,解决500问题 2.出现404状态码 一般是路径有错误或拼写错 ...
- 论文阅读-(ECCV 2018) Second-order Democratic Aggregation
本文是Tsung-Yu Lin大神所作(B-CNN一作),主要是探究了一种无序的池化方法\(\gamma\) -democratic aggregators,可以最小化干扰信息或者对二阶特征的内容均等 ...
- wpf 让正执行的程序暂停几秒钟
public static class DispatcherHelper { [SecurityPermissionAttribute(SecurityAction.Deman ...