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. gulp插件构建项目 压缩js、css、image、zip、web服务、跨域等插件

    推荐一个很好文: https://github.com/lin-xin/blog/issues/2 匹配符 *.**.!.{} gulp.src('./js/*.js') // * 匹配js文件夹下所 ...

  2. vue-cli中安装方法

    源:http://www.cnblogs.com/jn1223/p/6656956.html vue-cli中安装方法   vue-cli脚手架模板是基于node下的npm来完成安装的所以首先需要安装 ...

  3. 使用FileReader接口读取文件内容

    如果想要读取或浏览文件,则需要通过FileReader接口,该接口不仅可以读取图片文件,还可以读取文本或二进制文件,同时,根据该接口提供的事件与方法,可以动态侦察文件读取时的详细状态,接下来,我们详细 ...

  4. Android调用系统图库返回路径

    调用系统图库: Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI); ...

  5. ArrayList在foreach删除倒数第二个元素不抛并发修改异常的问题

    平时我们使用ArrayList比较多,但是我们是否知道ArrayList在进行foreach的时候不能直接通过list的add或者move方法进行删除呢, 原因就是在我们进行foreach遍历的时候, ...

  6. 小程序实践(五):for循环绑定item的点击事件

    微信展示列表效果借助于 wx:for  简单写一个列表(wxml文件中): 对应的数据源(js文件中): 写一个点击监听: 效果: 以上.可以实现列表的item点击效果,但是无法到点击的item对应的 ...

  7. Centos 中无法上网的问题

    我是 Centos 最小化安装的,安装网后 Centos 竟然无法上网...有点奇葩, 应该是网卡没有激活的问题了,下面是解决的过程 查看网卡 ip addr 其中 lo 是 Loop back ad ...

  8. tkinter进阶版——ttk

    很长的一段时间里,我都是用tkinter进行GUI设计的,还写过一篇<tkinter模块常用参数>. 但后来慢慢地觉得,这个tkinter真的是有点丑啊. 于是,找到了现在的ttk. tt ...

  9. mac上Docker安装&初体验

    Docker是什么? Docker是一个虚拟环境容器,可以将你的开发环境.代码.配置文件等一并打包到这个容器中,并发布和应用到任意平台中. 官方文档:https://docs.docker.com H ...

  10. WSL优化 (Windows Subsystem for Linux) Linux子系统优化配置

    目录 wsl优化 (Windows Subsystem for Linux) Linux子系统优化 1. 永久修改wsl终端字体 2. 修改Linux终端配色 3. 添加WSL到右键菜单 wsl优化 ...