Python 基础 装饰器
今天把学过的装饰器的知识进行回顾一下,说到装饰器,第一反应就是这个东西呢就是用来装逼的,为啥这样说呢,是应为没有这个东西照样可以干活,大部分工作都是可以做的,不管咋样还是把学过的装逼器梳理一下吧。
一、装饰器是个什么鬼?
装饰的意思呢,就是修饰,装点的意思可以给别的函数添加新的功能,器呢就是函数的意思,so 装饰器即是为别的函数添加新的功能的函数。
二、作为一个装饰器,他、它有什么样的规则呢?
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
三、如何实现一个装饰器呢?
要实现一个可以使用的装饰器就需要满足:装饰器=高阶函数+函数嵌套+闭包
四、高阶函数
上节介绍完了什么是高阶函数,只要满足:1.函数可以接受函数名当参数进行传递 2.函数的返回值可以返回一个函数名 只要能够满足上面的任何一条就认为构成的这个函数是高阶函数
高阶函数的例子:
- def foo():
- print('我的函数名作为参数传给高阶函数')
- def gao_jie1(func):
- print('我就是高阶函数1,我接收的参数名是%s' %func)
- func()
- def gao_jie2(func):
- print('我就是高阶函数2,我的返回值是%s' %func)
- return func
- gao_jie1(foo)
- gao_jie2(foo)
输出的结果是:
我就是高阶函数1,我接收的参数名是<function foo at 0x006896A8>
我的函数名作为参数传给高阶函数
我就是高阶函数2,我的返回值是<function foo at 0x006896A8>
- #高阶函数应用1:把函数当做参数传给高阶函数
- import time
- def foo():
- print('from the foo')
- def timmer(func):
- start_time=time.time()
- func()
- stop_time=time.time()
- print('函数%s 运行时间是%s' %(func,stop_time-start_time))
- timmer(foo)
- #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
- 把函数当做参数传给高阶函数
- #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
- import time
- def foo():
- print('from the foo')
- def timmer(func):
- start_time=time.time()
- return func
- stop_time=time.time()
- print('函数%s 运行时间是%s' %(func,stop_time-start_time))
- foo=timmer(foo)
- foo()
- #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
- 函数返回值是函数名
五、函数嵌套(就是函数中还有定义函数)
- def father(name):
- print('from father %s' %name)
- def son():
- print('from son')
- def grandson():
- print('from grandson')
- grandson()
- son()
- father('还是牛')
六、闭包:(在一个作用域中放入的定义变量,就像打了一个包)
- #闭包的概念:闭就是封装的意思,就是把变量分装起来;包:就是层的意思,与之前作用域意思是一样的。
- #grandson中的变量有name(形式参数);son中的变量有grandson(函数名也是变量);father中的变量有:name(形式参数) son
- def father(name):
- print('from the father %s' %(name))
- def son():
- print('from the son')
- def grandson():
- print('from the grandson %s'%(name))
- grandson()
- son()
- father('SB')
七、装饰器的基本框架
- def timmer(func):
- def wrapper():
- print(func)
- func()
- return wrapper
- def boo():
- print('你就是个傻逼!')
- res = timmer(boo) # 返回的是wrapper的内存地址 <function timmer.<locals>.wrapper at 0x02129420>
- #print(res)
- res() #是在执行wrapper 函数
八、装饰器的两种形式:
第一种 无参数的装饰器
- user_list=[
- {'name':'alex','passwd':''},
- {'name':'linhaifeng','passwd':''},
- {'name':'wupeiqi','passwd':''},
- {'name':'yuanhao','passwd':''},
- ]
- current_user={'username':None,'login':False}
- def auth_deco(func):
- def wrapper(*args,**kwargs):
- if current_user['username'] and current_user['login']:
- res=func(*args,**kwargs)
- return res
- username=input('用户名: ').strip()
- passwd=input('密码: ').strip()
- for index,user_dic in enumerate(user_list):
- if username == user_dic['name'] and passwd == user_dic['passwd']:
- current_user['username']=username
- current_user['login']=True
- res=func(*args,**kwargs)
- return res
- break
- else:
- print('用户名或者密码错误,重新登录')
- return wrapper
- @auth_deco
- def index():
- print('欢迎来到主页面')
- @auth_deco
- def home():
- print('这里是你家')
- def shopping_car():
- print('查看购物车啊亲')
- def order():
- print('查看订单啊亲')
- print(user_list)
- # index()
- print(user_list)
- home()
第二种 含有参数的装饰器
- user_list=[
- {'name':'alex','passwd':''},
- {'name':'linhaifeng','passwd':''},
- {'name':'wupeiqi','passwd':''},
- {'name':'yuanhao','passwd':''},
- ]
- current_user={'username':None,'login':False}
- def auth(auth_type='file'):
- def auth_deco(func):
- def wrapper(*args,**kwargs):
- if auth_type == 'file':
- if current_user['username'] and current_user['login']:
- res=func(*args,**kwargs)
- return res
- username=input('用户名: ').strip()
- passwd=input('密码: ').strip()
- for index,user_dic in enumerate(user_list):
- if username == user_dic['name'] and passwd == user_dic['passwd']:
- current_user['username']=username
- current_user['login']=True
- res=func(*args,**kwargs)
- return res
- break
- else:
- print('用户名或者密码错误,重新登录')
- elif auth_type == 'ldap':
- print('巴拉巴拉小魔仙')
- res=func(*args,**kwargs)
- return res
- return wrapper
- return auth_deco
- #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
- #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
- @auth(auth_type='ldap')
- def index():
- print('欢迎来到主页面')
- @auth(auth_type='ldap')
- def home():
- print('这里是你家')
- def shopping_car():
- print('查看购物车啊亲')
- def order():
- print('查看订单啊亲')
- # print(user_list)
- index()
- # print(user_list)
- home()
Python 基础 装饰器的更多相关文章
- python基础——装饰器
python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...
- python基础—装饰器
python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...
- python 基础——装饰器
python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...
- day5学python 基础+装饰器内容
基础+装饰器内容 递归特性# 1.必须有一个明确的结束条件# 2.每次进入更深一层递归时,问题规模相比上次递归应有所减少# 3.递归效率不高 def run(n): print(n) if int(n ...
- Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle
目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...
- python基础 (装饰器,内置函数)
https://docs.python.org/zh-cn/3.7/library/functions.html 1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使 ...
- python基础-装饰器,生成器和迭代器
学习内容 1.装饰器 2.生成器 3.迭代器 4.软件目录结构规范 一:装饰器(decorator) 1.装饰器定义:本质就是函数,用来装饰其他函数,即为其他函数添加附加功能. 2.装饰器原则:1)不 ...
- python基础===装饰器@property 的扩展
以下来自Python 3.6.0 Document: class property(fget=None, fset=None, fdel=None, doc=None) Return a proper ...
- <Python基础>装饰器的基本原理
1.装饰器 所谓装饰器一般是对已经使用(上线)的函数增加功能. 但是因为一般的大公司的严格按照开放封闭原则(对扩展是开放的,对修改是封闭的),不会让你修改原本的函数. 装饰器就是在不改变原本的函数且不 ...
- python基础-装饰器
一.什么是装饰器 装饰器本质就是函数,功能是为其他函数附加功能 二.装饰器遵循的原则 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 三.实现装饰器的知识储备 装饰器=高阶函数+函数嵌套 ...
随机推荐
- Ubuntu16.04 安装apache+mysql+php(LAMP)
记录下ubuntu环境下安装apache+mysql+php(LAMP)环境. 0x01安装apache sudo apt-get update sudo apt-get install apache ...
- web项目中登陆超时的功能实现(基于C#)
当我们登陆进网站后,中途去看别的东西,没有再与该网站的服务器交互,就会弹出一个js窗口,登陆超时请重新登陆,并跳转到登陆页面. 步骤1.实现原理,在web.config中配置session的超时时间, ...
- [POJ3107] Godfather - 暴力枚举(树的重心)
Godfather Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8728 Accepted: 3064 Descrip ...
- 21.Nginx代理缓存
1.环境准备 操作系统 应用服务 外网地址 内网地址 CentOS7.6 LB01 10.0.0.5 172.16.1.5 CentOS7.6 Web01 10.0.0.7 172.16.1.7 2. ...
- 06 Node.js学习笔记之自动路由
在以往客户端请求的文件,我们都得判断匹配才能返回相应的数据,其实我们可以设置一个自动路由,就可以不用每次去判断用户访问的是那个文件了 //1.载入http和fs模块 var http=require( ...
- Mybaits 源码解析 (一)----- 搭建一个mybatis框架(MyBatis HelloWorld)
源码分析之前先搭一个mybatis的demo,这个在看源码的时候能起到了很大的作用,因为在看源码的时候,会恍然大悟,为什么要这么配置,为什么要这么写.(老鸟可以跳过这篇) 开发环境的准备 创建mave ...
- mp-vue实现小程序回顶操作踩坑,wx.pageScrollTo使用无效填坑
本来项目都写的差不多了,测试测着侧着就冒出了新的想法,我因为做的是问卷,因此会有用户必答题未答完的可能存在,本来市场部给的需求就是做一个弹窗就好了,她说想要做出跳回到用户未答的第一道题,好吧,既然都这 ...
- GStreamer基础教程11 - 与QT集成
摘要 通常我们的播放引擎需要和GUI进行集成,在使用GStreamer时,GStreamre会负责媒体的播放及控制,GUI会负责处理用户的交互操作以及创建显示的窗口.本例中我们将结合QT介绍如何指定G ...
- The usage of Markdown---引用
目录 1. 序言 2. 引用与嵌套引用 3. 列表中的引用 更新时间:209.09.14 1. 序言 在本篇,我们来仔细谈一下Markdown的引用. 2. 引用与嵌套引用 在Markdown ...
- Java基础(十三)内部类(inner class)
1.内部类是定义在另一个类中的类.使用内部类的原因有: 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据 内部类可以对同一个包中的其他类隐藏起来 当想要定义一个回调函数且不想编写大量代码 ...