装饰器就是一个函数,他是通过不修改某个函数的源代码和调用方式的前提下可以添加新功能的一种函数。在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 学习第四点-装饰器的更多相关文章

  1. Python学习笔记:装饰器

    Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...

  2. Python学习笔记012——装饰器

    1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...

  3. python学习之day5,装饰器,生成器,迭代器,json,pickle

    1.装饰器 import os import time def auth(type): def timeer(func): def inner(*args,**kwargs): start = tim ...

  4. python学习笔记:装饰器2

    python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...

  5. Python学习——迭代器&生成器&装饰器

    一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...

  6. 从零开始的Python学习Episode 11——装饰器

    装饰器 装饰器是用来处理其他函数的函数,主要作用是在不修改原有函数的情况下添加新的功能,装饰器的返回值也是一个函数对象. 简单的装饰器 import time def show_time(f): de ...

  7. python学习笔记(五):装饰器、生成器、内置函数、json

    一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...

  8. Python学习系列之装饰器

    装饰器的作用 装饰器用于装饰某个函数.方法或者类,它可以让这个函数执行之前或者执行之后做一些操作 手工实现一个装饰器 def outer(some_func): #装饰器 $1 def inner() ...

  9. Python学习日记(九) 装饰器函数

    1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...

  10. Python 学习 —— 进阶篇(装饰器、类的特殊方法)

    Python基础部分学完之后,在进入其OOP部分前,先理解一下其装饰器这种结构,其功能可类比于Java中的面向切面编程,下面参见具体实例: def log(f): def fn(x): print ' ...

随机推荐

  1. PHP算法之增减字符串匹配

    给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length. 返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i ...

  2. ASCII, Unicode 与 UTF-8

    1,ASCII 由于计算机是美国人发明的,最早只有127个字符,即大小写英文字母.数字.一些符号,被编码到计算机里,这个编码表就是ASCII表.这时每个字符用1 Byte表示. 2,Unicode 当 ...

  3. input、textarea等输入框输入中文时,拼音在输入框内会触发input事件的问题

    监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 但是在很多情况下,只需要输入到输入框的中文字符. 解决办法: 通过查阅资料得知在 ...

  4. 数据库实例性能调优利器:Performance Insights

    Performance Insights是什么 阿里云RDS Performance Insights是RDS CloudDBA产品一项专注于用户数据库实例性能调优.负载监控和关联分析的利器,以简单直 ...

  5. thinkphp 空控制器

    空控制器的概念是指当系统找不到请求的控制器名称的时候,系统会尝试定位空控制器(EmptyController),利用这个机制我们可以用来定制错误页面和进行URL的优化. 大理石平台价格表 现在我们把前 ...

  6. js 实现 map 工具类

    /* * MAP对象,实现MAP功能 * * 接口: * size() 获取MAP元素个数 * isEmpty() 判断MAP是否为空 * clear() 删除MAP所有元素 * put(key, v ...

  7. .net core, docker 在vs2019开发过程中的问题以及解决办法

    .net core, docker 在vs2019开发过程中的问题以及解决办法 记录下来,帮助Ta人~ 1.vs调试,快Build完后提示Docker 端口:xxxx,xxxx,xxxx占用 解决办法 ...

  8. Berlekamp Massey算法求线性递推式

    BM算法求求线性递推式   P5487 线性递推+BM算法   待AC.   Poor God Water   // 题目来源:ACM-ICPC 2018 焦作赛区网络预赛 题意   God Wate ...

  9. 王者归来,Java 程序设计葵花宝典!

    致谢  感谢所有关注本号的小伙伴们,这一年来本号的茁壮成长离不开大家的支持. 2018年,继续坚持分享以及为大家谋求福利!!! Java技术栈往期赠书 赠书一:新春第一次送书,价值78元 X 3本 赠 ...

  10. USACO 2006 November Gold Fence Repair /// 贪心(有意思)(优先队列) oj23940

    题目大意: 输入N ( 1 ≤ N ≤ 20,000 ) :将一块木板分为n块 每次切割木板的开销为这块木板的长度,即将长度为21的木板分为13和8,则开销为21 接下来n行描述每块木板要求的长度Li ...