一、装饰器:

本质就是函数,功能:为其他函数添加附加功能

原则:

1.不能修改被装饰函数的源代码

2.不能修改被修饰函数的调用方式

一个简单的装饰器

import time
def timmer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
stop_time = time.time()
print('函数运行的时间%s'%(stop_time - start_time)) return res
return wrapper @timmer
def cal(l):
res = 0
for i in l:
time.sleep(0.01)
res += i
return res
ret = cal(range(200))
print(ret)

二、装饰器的知识储备

装饰器 = 高阶函数 + 函数嵌套 + 闭包

高阶函数定义:

1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

用高阶函数模拟装饰器:

结果多运行了一次

import time
def foo():
time.sleep(3)
print('来自foo') def timmer(func):
start_time = time.time()
func()
stop_time = time.time()
print('函数运行的时间是%s' %(stop_time - start_time))
return func
foo = timmer(foo)
foo()

  

三、 函数嵌套及闭包

嵌套就是,函数里再定义函数

闭包:闭----->封装的变量   包----->一层层函数

每个包找变量先从自身那层开始找,找不到再从外层找

重点:函数即变量

def father(name):

    def son():
print('我的爸爸是%s' %name)
def grandson():
name = 'China'
print('我的爷爷是%s' %name)
grandson()
son()
father('河南')

装饰器框架

def timmer(func):
def wrapper():
#增加功能
func() return wrapper

补充该装饰器架子

import time
def timmer(func):
def wrapper():
#增加功能
start_time = time.time()
func()
stop_time = time.time()
print('运行时间是%s'%(stop_time - start_time))
return wrapper def test():
time.sleep(2)
print('test函数运行完毕') res = timmer(test) #返回的是wrapper的地址
res() #执行的是wrapper()

可以看出,只要把函数的最后两行代码的函数接收值改为:test

test= timmer(test)

test() 

看起来符合装饰器原则

但每次给函数增加功能都得写一遍 test= timmer(test),显然不合理

所以,用@timmer 去代替test = timmer(test)

import time
def timmer(func):
def wrapper():
#增加功能
start_time = time.time()
func()
stop_time = time.time()
print('运行时间是%s'%(stop_time - start_time))
return wrapper
@timmer #就相当于:test = timmer(test)
def test():
time.sleep(2)
print('test函数运行完毕')
test()

四、加上返回值的装饰器

import time
def timmer(func):
def wrapper():
#增加功能
start_time = time.time()
res = func() #这里执行的函数test,所以要在这里给函数一个接收返回值的变量
stop_time = time.time()
print('运行时间是%s'%(stop_time - start_time))
return res #这里要返回test的返回值
return wrapper
@timmer #就相当于:test = timmer(test)
def test():
time.sleep(2)
print('test函数运行完毕')
return '这是test的返回值'
a = test()
print(a)

五、加上参数的装饰器

import time
def timmer(func):
def wrapper(*args, **kwargs): #可接受任意值
#增加功能
start_time = time.time()
res = func(*args, **kwargs) #将wrapper接受的值原封传给func
stop_time = time.time()
print('运行时间是%s'%(stop_time - start_time))
return res
return wrapper
@timmer #就相当于:test = timmer(test)
def test1(name, age, gander):
time.sleep(2)
print('test1运行结果名字为%s年龄为%d性别为%s'%(name, age, gander))
return '这是test1的返回值'
a = test1('jinling', 20, 'female')
print(a) @timmer
def test2(name, age):
time.sleep(3)
print('test2函数运行结果名字为%s年龄为%d'%(name, age))
return '这是test2的返回值'
b = test2('liuwen', 18)
print(b)

六、实现一个验证功能装饰器

def func_ver(func):
def wrapper(*args, **kwargs):
name1 = input('请输入用户名:')
pd = input('请输入用户密码:')
if name1 == 'PJL' and pd == '123':
func(*args, **kwargs)
else:
print('用户名或密码错误') return wrapper @func_ver
def index():
print('欢迎来到的我的网站')
@func_ver
def home(name):
print('%s欢迎回家'%name)
@func_ver
def secrect(name):
print('%s这是你的小秘密'%name) index()
home('jinling')
secrect('jining')

 

 

  

python课堂整理21---初识装饰器的更多相关文章

  1. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  2. 初学 Python(十五)——装饰器

    初学 Python(十五)--装饰器 初学 Python,主要整理一些学习到的知识点,这次是生成器. #-*- coding:utf-8 -*- import functools def curren ...

  3. Python 函数修饰符(装饰器)的使用

     Python 函数修饰符(装饰器)的使用 1.  修饰符的来源修饰符是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 修饰符是解决这类问题的绝佳设计, ...

  4. Python基础(八)装饰器

    今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f ...

  5. Python(三)对装饰器的理解

    装饰器是 Python 的一个重要部分,也是比较难理解和使用好的部分.下面对装饰器做一下简单整理 1. 前言 装饰器实际上是应用了设计模式里,装饰器模式的思想: 在不概念原有结构的情况下,添加新的功能 ...

  6. Python函数07/有参装饰器/多个装饰器装饰一个函数

    Python函数07/有参装饰器/多个装饰器装饰一个函数 目录 Python函数07/有参装饰器/多个装饰器装饰一个函数 内容大纲 1.有参装饰器 2.多个装饰器装饰一个函数 3.今日总结 3.今日练 ...

  7. 简学Python第四章__装饰器、迭代器、列表生成式

    Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群  群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...

  8. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  9. Python 标准库中的装饰器

    题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...

随机推荐

  1. Spring单例模式多线程安全问题-有状态的Bean

    Spring单例与线程安全小结 一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思 ...

  2. grub密码

    [root@lnmp ~]# grub-md5-cryptPassword: Retype password: $1$k9fQ//$Fh3/O8i3.9dw4zarIHtIx1 [root@lnmp ...

  3. kubernetes实战篇之为默认账户创建镜像拉取密钥

    系列目录 上一节我们分别使用纯文本账户密码和docker的config文件一创建一个kubernetes secret对象,并且把它添加到containers的imagePullSecrets字段用以 ...

  4. (Demo分享)利用原生JavaScript-ScrollLeft-实现做轮播广告通知

    轮播广告通知整体思路: 1.首先文字的移动利用了JAVA script 中ScrollLeft的知识点: 2.在设置一条一模一样的新闻,利用无缝轮播图滚动的原理让新闻无缝滚动. 3.使用了自执行匿名函 ...

  5. HTML行内元素、块级元素、行内块级元素的特点与区别

    元素 HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码. 元素分类方式 HTML 可以将元素分类方式分为行内元素.块状元素和行内块状元素三种,这三者可以通过设 ...

  6. SpringMVC_One

    SpringMVC_One SpringMVC的优势 (面试) 清晰的角色划分: 前端控制器(DispatcherServlet) 请求到处理器映射器(HandlerMapping) 处理器适配器(H ...

  7. flask请求上下文 (转)

    本篇阅读目录 一.flask中的CBV 二.werkzeug + 上下文初步解读 三.偏函数和线程安全 回到顶部 一.flask中的CBV 对比django中的CBV,我们来看一下flask中的CBV ...

  8. AlwaysOn 执行备份任务

    备份 使用维护计划向导创建备份 启动维护计划向导 填入计划名称,选择每项任务单独计划 选择完整备份和清除任务 配置完整备份任务,选择备份数据库 设置备份文件保存位置, 指定压缩备份,设置执行计划时间为 ...

  9. IDM 6.27.5(Internet Download Manager)中文破解版下载神器

    IDM一直是我最喜欢的下载工具,感觉用的比迅雷爽,简单使用,对付网盘有一套.IDM(Internet Download Manager)和迅雷的下载提速方式不同,从原理上来说,IDM速度较稳定,迅雷下 ...

  10. 关系型数据库MySql简介

    什么是关系型数据库? 数据库就是用来存储数据的仓库,是一种特殊的文件. 根据存储的数据不同,划分为关系型数据库和非关系型数据库. 关系型数据库就是指 建立在关系模型基础上的数据库,通俗来讲这种数据库就 ...