1. 定义(如何理解装饰器):装饰器本生是闭包函数的一种应用,是指在不改变原函数的情况下为原函数添加新的功能的一个函数。它把被装饰的函数作为外层函数的参数传入装饰器,通过闭包操作后返回一个替代版函数。
  2. 遵循的原则: 开放封闭原则------在不改变调用方式和源代码的情况下,增加新功能。
    1. 不能改变被修饰对象(函数(后面还会对类进行装饰))的源代码(封闭)
    2. 不能改变被修饰对象(函数(以后还会对类进行装饰))的调用方式,且能达到增加功能的效果。(开放)
  3. 优点:
    1. 丰富了原函数的功能
    2. 提高了程序的可拓展性
  4. 装饰器的简单实现:
# 无参装饰器公式:
def fn():
print('原功能') def outer(fn):
def inner():
print('新功能1')
fn()
print('新功能2')
return inner
fn = outer(fn1)
print(fn())
"""
案例分析: 定义一个打印插花的函数,为其前面添加绘画功能,后面添加观赏功能。
如何一步一步完成完整的装饰器函数。
""" def vase():
print('插花') def wrap():
tag = vase # 此时的vase 是在wrap()还没有运行结束的时候,wrap没有返回值,所以tag被赋值的是vase原先的值。 def outer():
print('绘画')
tag() # 原先的vase
print('观赏') return outer # wrap()函数返回的是outer函数的地址空间 vase = wrap() # vase = outer vase()

上述代码,存在一个缺陷,就是没有写活,没办法将装饰器用在其他函数上,对于无参装饰器的正确的姿势应该如下:

def vase():
print('插花') def wrap(fn):
def outer():
print('绘画')
fn() # 原先的vase
print('观赏') return outer vase = wrap(vase) # vase = outer() vase()

那么如何让代码更简洁? python 提供一种语法糖,可以让代码看起来更简洁

def wrap(fn):
def outer():
print('绘画')
fn() # 原先的vase
print('观赏') return outer @wrap # 此语法糖形式,实际上就是完成了 vase = wrap(vase)操作 = outer
def vase():
print('插花') print(vase())

下面来看看如何进行多层装饰:(多层装饰注意一个顺序问题,执行时是从上向下执行,返回操作的时候是一层一层跳出)

def wrap1(fn):
def outer():
print('绘画')
fn() # 原先的vase
print('观赏') return outer def wrap2(fn):
def outer():
print('购买')
fn() # 原先的vase return outer @wrap2
@wrap1
def vase():
print('插花') vase() # 购买
# 绘画
# 插花
# 观赏 @wrap1
@wrap2
def vase():
print('插花') vase() # 绘画
# 购买
# 插花
# 观赏

5.有参有返的装饰器

def wrap(func):
def inner(*args, **kwargs): # 此处 *args (接收所有位置参数) 接收(a,b,c)以元组形式存储,kwargs (接收所有关键字参数) 则是接收{x:4,y:5,z:6}存成字典形式
print('新功能1')
res = func(*args, **kwargs)
print('新功能2')
return res return inner @wrap
def fn(a, b, c, *, x, y, z):
print(a, b, c, x, y, z) re = fn(1, 2, 3, x=4, y=5, z=6)
print(re) # 新功能1
# 1 2 3 4 5 6
# 新功能2
# None 返回值是None 因为函数fn本身无return

案例:在原登录功能下增加账号验证和密码验证功能

# 增加一个账号安全处理功能:3位英文字母或汉字
def check_pwd(fn):
def inner(usr, pwd):
if not (len(pwd) >= 6 and usr.isalpha()):
print('账号认证失败')
return False
return fn(usr, pwd) return inner # 增加一个密码处理功能 : 6位以上英文和数字组合 def check_usr(fn): # login = check_usr(login) = inner
def inner(usr, pwd):
if not (len(usr) >= 3 and usr.isalnum()):
print('密码认证失败')
return False
return fn(usr, pwd) return inner @check_usr # login = inner # 语法糖 谁现在下面谁先装功能,套在最外面(上面的)的是最先执行的
@check_pwd
# 登录功能
def login(usr, pwd):
if usr == 'qwe' and pwd == '':
print('登录成功')
return True
print('登录失败')
return False res1 = login('asdd', '')
res2 = login('as', '')
res3 = login('qwe', '')
res4 = login('qwe', '')
print(res1)
print(res2)
print(res3)
print(res4) # 账号认证失败
# 密码认证失败
# 账号认证失败
# 登录成功
# False
# False
# False
# True

带参装饰器(def wrap(参数们))

# 通过带参装饰器,实现增加颜色选择功能
def color_choice(color_inp):
def wrap(fn):
if color_inp == 'red':
info = 'red:new action'
else:
info = 'yellow:new action' def inner(*args, **kwargs):
res = fn(*args, **kwargs)
print(info)
return res return inner # wrap(fn) 返回的是 inner函数对象(地址) return wrap # color_choice 返回的是 wrap函数对象 color_choice(color_inp)() => wrap() => res color_inp = input('color:') @color_choice(color_inp)
def func():
print('func run ') func()

案例:查看个人主页前的登录状态验证

is_login = False

def login():
usr = input('usr:').lower()
if not (len(usr) >= 3 and usr.isalnum()):
print('密码认证失败')
return False
pwd = input('pwd:')
if usr == 'qwe' and pwd == '':
print('登录成功')
is_login = True
else:
print('登录失败')
is_login = False # 完成一个登录状态校验的装饰器
def check_login(fn):
def inner(*args, **kwargs):
if is_login != True:
print('你未登录')
login()
res = fn(*args, **kwargs)
return res
return inner # 查看个人主页功能
@check_login
def homepage():
print('个人主页') @check_login
# 销售功能
def sell():
print('销售页面') homepage()

day12--装饰器的更多相关文章

  1. day12:装饰器的进阶

    1,三元运算符:变量 = 条件返回True的结果 if 条件 else 条件返回false的结果:必须要有结果:必须要有if和else,只能是简单的情况. 2,传参包起来,星号打散 def outer ...

  2. day12 装饰器的模版

    1.什么是装饰器 装饰器指的是为被装饰对象(别人)添加新功能的工具 装饰器本身可以是任意可调用对象 被装饰器对象也可以是任意可调用对象 2.为何要用装饰器 开放封闭原则:指的是对修改封闭,对扩展开放 ...

  3. 总结day12 ----装饰器

    一,什么是装饰器? 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事 ...

  4. Day12装饰器

    1.装饰器 什么是装饰器:装饰器指的是为被装饰对象添加新功能的工具 装饰器本身可以是任意调用对象 被装饰对象本身也可以是任意可调用对象 2.为何要用装饰器: 开放封闭原则: ①对修改源代码和调用方式是 ...

  5. day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)

    day11:装饰器(装饰器形成.装饰器作用.@语法糖.原则.固定模式) 装饰器形成:最简单的.有返回值的.有一个参数的.万能参数 函数起的作用:装饰器用于在已经完成的函数前后增加功能 语法糖:使代码变 ...

  6. Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)

    一.nonlocal关键字 1.作用:将L与E(E中的名字需要提前定义)的名字统一 2.应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值 def outer(): num=10 print ...

  7. DAY12、装饰器

    一.补充:nonlocal关键字 1.作用:将L与E(E中的名字需要提前定义)的名字统一 2.应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值 3.案例: def outer():    ...

  8. day12 十二、开放封闭、装饰器

    一.nonlocal关键词 # global # num = # def fn(): # global num # L>G 将局部的名字与全局统一 # num = # fn() # print( ...

  9. python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)

    函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...

  10. 函数的有用信息,装饰器 day12

    一 函数的有用信息 本函数的功能:绘图功能,实时接收数据并绘图.:return: 绘图需要的数据,返回给前端某标签 def f1(): ''' 本函数的功能:绘图功能,实时接收数据并绘图. :retu ...

随机推荐

  1. react-conponent-hellocynthia

    <!DOCTYPE html> <html> <head> <script src="../../build/react.js">& ...

  2. javascript 里面 with 关键字

    1.with的基本概念 with语句的作用是将代码的作用域设置到一个特定的作用域中,目的是为了简化多次编写访问同一对象的工作.基本语法如下: with (expression) statement 下 ...

  3. CSS3效果:5种预载动画效果

    实现如图所示的动画效果: 预载动画一:双旋圈 在两个不同方向旋转的圆圈.我们对内圈的转速定义了一个CSS代码,即内圈比外圈的速率快2倍.实现如图所示: html代码: <body style=& ...

  4. matlab练习程序(波纹扭曲)

    其实就是用sin或cos对x,y坐标进行变换,处理的时候依然是反向变换. 类似的,用不同的函数能得到不同的扭曲效果,比如log,1/x,exp等等. 效果如下: 代码如下(还给出了如何生成gif图片的 ...

  5. 使用vuejs2.0和element-ui 搭建的一个后台管理界面

    说明: 这是一个用vuejs2.0和element-ui搭建的后台管理界面. 相关技术: vuejs2.0:一套构建用户界面的渐进式JavaScript框架,易用.灵活.高效. element-ui: ...

  6. Visual Studio Team Services 动手实验

    Visual Studio Team Services 动手实验 概述 为Visual Studio Team Services提供的动手实验,要完成实验首先需要满足以下条件: Visual Stud ...

  7. MyBatis笔记----MyBatis 入门经典的两个例子: XML 定义与注解定义

    ----致敬MyBatis官方开放文档让大家翻译,不用看书直接看文档就行了,mybatis的中文文档还需要完备的地方 简介 什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以 ...

  8. kali2016.2(debian)快速安装mysql5.7.17

    糊里糊涂的删除了kali原本的mysql5.6.27版本,原本的mysql与很多软件关联在一起,每次安装都失败,后来把相关的都卸载了(悲催的浪费了一天) 下载地址  debian mysql下载地址 ...

  9. [20190305]删除审计登录信息不适合使用logrotate.txt

    [20190305]删除审计登录信息不适合使用logrotate.txt --//生产系统数据库sys用户登录会在/u01/app/oracle/admin/${ORACLE_SID}/adump/目 ...

  10. netsh winsock reset命令,作用是重置 Winsock 目录

    Win xp重置 编辑 要为 Windows XP 重置 Winsock,请按照下列步骤操作: 1.单击“开始”,运行中输入cmd. 2.然后输入命令 netsh winsock reset. 3.重 ...