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. ThinkPHP框架知识

    php框架 一.真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困难,代码风格 ...

  2. Python property使用简介

    property使用简介 by:授客 QQ:1033553122 功能简介 1) 把类方法变成只读属性 2) setter和getter的另一种实现 代码演示1 #!/usr/bin/env pyth ...

  3. Java判断一个字符是否是数字的几种方法的代码

    在工作期间,将写内容过程经常用到的一些内容段做个记录,下面内容是关于Java判断一个字符是否是数字的几种方法的内容,希望能对码农们有好处. public class Test{ public stat ...

  4. c++预声明类引发的无法解析外部符号问题

    在VisualStudio下开发C++程序常遇到链接问题就是:LNK2019 无法解析外部符号. 这个问题一般我们认为是没有将引用的代码链接到当前项目造成,也有例外,就是下面我要说的预声明类导致的. ...

  5. Java:字节流和字符流(输入流和输出流)

    本文内容: 什么是流 字节流 字符流 首发日期:2018-07-24 什么是流 流是个抽象的概念,是对输入输出设备的抽象,输入流可以看作一个输入通道,输出流可以看作一个输出通道. 输入流是相对程序而言 ...

  6. Django JsonResponse与HttpResponse重要区别

    JsonResponse是HttpResponse的一个子类,是Django提供的用于创建JSON编码类型响应的快捷类.它的默认Content-Type头部设置为application/json,它的 ...

  7. django 下载文件

    方法一. from django.http import StreamingHttpResponse def big_file_download(request): # do something... ...

  8. C#发布和调试WebService

    一.编写并发布WebService服务 1.新建空web应用程序

  9. Linux atop 监控系统状态

    atop是一个功能非常强大的linux服务器监控工具,它的数据采集主要包括:CPU.内存.磁盘.网络.进程等,并且内容非常的详细,特别是当那一部分存在压力它会以特殊的颜色进行展示,如果颜色是红色那么说 ...

  10. c/c++ 重载new,delete运算符 placement new

    重载new,delete运算符 new,delete在c++中也被归为运算符,所以可以重载它们. new的行为: 先开辟内存空间 再调用类的构造函数 开辟内存空间的部分,可以被重载. delete的行 ...