#装饰器:本质就是函数,为其他函数附加功能
原则:
1、不修改被修饰函数的源代码
2、不修改被修饰函数的调用方式

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

#高阶函数

'''
高阶函数定义:
1、函数接受的参数是一个函数名
2、函数的返回值是一个函数名
3、满足上述条件任意一个,都可称之为高阶函数
''' # 函数接受的参数是一个函数名的情况下,要改变函数的调用方式
def foo():
time.sleep(2)
print("憨憨你好") def test(func):
print(func)
start_time=time.time()
func()
stop_time=time.time()
print('函数的运行时间是%s' %(stop_time-start_time)) test(foo) # 修改了函数的调用方式 # 函数的返回值是一个函数名,此时不需要改变函数调用方式
def foo():
print('from the foo') def test(func):
return func foo = test(foo)
foo() 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):
print('from father %s' % name) def son():
print('他的爸爸是%s' % name) def grandson():
print('他的爷爷是%s' % name) grandson() son() father('憨憨')

#装饰器例子

# 打印1+2+3+..+100 并且打印出运行时间
import time def cal(l):
start_time = time.time()
res = 0
for i in l:
time.sleep(0.01)
res += i
stop_time = time.time()
print("函数的运行时间是%s" % (stop_time - start_time))
return res print(cal(range(100))) 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(f):
res = 0
for i in f:
time.sleep(0.1)
res += i
return res print(cal(range(100)))

#函数镶嵌 装饰器的实现

def timmer(func):
def wrapper():
start_time = time.time()
func() # 运行的就是test
stop_time = time.time()
print('运行时间是%s' % (stop_time - start_time)) return wrapper @timmer # 相当于 test=timmer(test)
def test():
time.sleep(3)
print('test已经运行') test()

# 例子1:为京东商城中的一些方法加上验证装饰器

# 将下列方法加上验证装饰器
current_dic = {'username': None, 'login': False} user_list = [
{'name': 'hanhan', 'pwd': ''},
{'name': 'amei', 'pwd': ''},
{'name': 'ahao', 'pwd': ''}
] def yanzheng(func):
def wrapper(*args, **kwargs):
if current_dic['username'] and current_dic['login']:
res = func(*args, **kwargs)
return res
username = input('输入用户名:').strip()
pwd = input('输入密码:').strip()
for user_dic in user_list:
if username == user_dic['name'] and pwd == user_dic['pwd']:
current_dic['username'] = username
current_dic['login'] = True
res = func(*args, **kwargs)
return res
else:
print('输入的用户名和密码有误') return wrapper @yanzheng
def index():
print('欢迎来到京东商城') @yanzheng
def jiaose(name):
print('进入%s页面' % (name)) @yanzheng
def shopping_car(name):
print('%s购物车里面有[%s,%s,%s]' % (name, '飞机', '火箭', '娃娃')) index()
jiaose('管理员')
shopping_car('产品经理')

Python学习第十一课——装饰器的更多相关文章

  1. python学习日记(函数--装饰器)

    楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...

  2. python第二十六课——装饰器

    装饰器是闭包的一种使用场景: python中的装饰器在定义上需要传入一个函数对象, 在此函数执行之前或者之后都可以追加其它的操作, 这样做的好处是,在不改变源码(原本业务逻辑的)同时,进行功能的扩展: ...

  3. 【Python学习之二】装饰器

    装饰器 首先,给出装饰器的框架: def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return ...

  4. python 学习笔记7(装饰器)

    闭包(closure)是函数式编程的重要的语法结构. 定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). def outer ...

  5. Python 学习笔记9(装饰器,decorator)

    31 装饰器 装饰器可以对一个函数.方法或者类进行加工,是一种高级的python语法. 装饰函数 接收一个可调用对象作为输入参数,并返回一个新的可调用对象. 把函数传递给装饰器,然后增加新的功能,返回 ...

  6. Python学习笔记九:装饰器,生成器,迭代器

    装饰器 本质是函数,装饰其他函数,为其他函数添加附加功能 原则: 1不修改原函数的源代码 2不修改原函数的调用方式 知识储备: 1函数即变量 使用门牌号的例子说明函数,调用方式与变量一致 2高阶函数 ...

  7. Python学习第二阶段,day1, 装饰器,生成器,迭代器

    装饰器 不得不说,这是对初学者最难以理解的概念了,虽然我学过面向对象,但还是被搞懵逼了..前面还好理解,主要是后面“装饰器的装饰器”我理解不了.装饰器工厂,根据传入的参数不同去返回不同的装饰器,我不得 ...

  8. Python学习之--函数/生成器/装饰器

    Function,函数,主要是为了:1提高代码的复用程度,2将程序模块化. 定义函数 在Python中,使用def 用来定义函数,一般函数的定义如下: def name(arg1,arg2,....) ...

  9. Python学习之路7☞装饰器

    一:命名空间与作用域 1.1命名空间 局部命名空间: def foo(): x=1 def func(): pass 全局命名空间: import time class ClassName:pass ...

随机推荐

  1. 单机架设传奇服务器第47课:定时器OnTimer功能详解

    传奇定时器OnTimer功能详解(泡点.时间触发.任务活动) 定时器功能,是服务端中非常常见的一种功能,常见如:泡点脚本.赌博脚本,任务活动指定时间刷怪,时间触发一些都需要用到OnTimer功能,定时 ...

  2. nodejs的req取参req.body,req.params,req.query

    1/req.query: Get:/domo?name=ximiximi&blog=https://home.cnblogs.com/u/ximiximi-blog/ app.get('/do ...

  3. selenium 使用close和quit关闭driver的不同点

    Driver.Quit()与Driver.Close()的不同:Driver.Quit(): Quit this dirver, closing every associated windows;Dr ...

  4. Sql性能优化梳理

    前言 先简单梳理下Mysql的基本概念,然后分创建时和查询时这两个阶段的优化展开. 1.0 基本概念简述 1.1 逻辑架构 第一层:客户端通过连接服务,将要执行的sql指令传输过来 第二层:服务器解析 ...

  5. opencv:图像模糊

    高斯模糊 #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespa ...

  6. 洛谷 P1043 数字游戏(区间dp)

    题目链接:https://www.luogu.com.cn/problem/P1043 这道题与石子合并很类似,都是把一个环强制改成一个链,然后在链上做区间dp 要初始化出1~2n的前缀和,方便在O( ...

  7. Shiro入门学习之shi.ini实现认证及源码分析(二)

    一.Shiro.ini文件 1.文件说明 ①ini(InitializationFile)初始文件:Window系统文件扩展名 ②Shiro使用时可以连接数据库,也可以不连接数据库(可以使用shiro ...

  8. 【嵌入式】ARM9复习

    一.嵌入式系统基础 二.ARM处理器 1. 在每条指令后,用;//注释这条指令的寻址方式,以及实现的功能(25分) 注:变址寻址需要标注是基址加偏移.还是基址加索引,是前变址还是后变址.SUB SP, ...

  9. Linux 笔记:虚拟控制台

    登录后按Alt+F2键这时又可以看到"login:"提示符,这个就是第二个虚拟控制台. 一般新安装的Linux有四个虚拟控制台,可以用Alt+F1~Alt+F4来访问. 虚拟控制台 ...

  10. 三天的Python课程

    基础很sb但必须熟练掌握: 第一天就是Python的简单介绍与简单的接触.基本都是概念性的东西,需要知道一个非常便捷的IDE工具:pycharm,以后的编程就靠它了.还有就是%s和%d的格式化输出.运 ...