python迭代器、生成器、装饰器之装饰器
装饰器。。。。。。
定义:本质是函数,为其他函数添加附加功能
原则: 1.不能修改被装饰的函数的源代码
2.不能修改被装饰函数的调用方式
仔细观察下面代码,看看有什么发现。
内嵌函数+高阶函数+闭包=》装饰器
import time
# 内嵌函数
def timmer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
stop_time = time.time()
print('run time is %s' % (stop_time - start_time))
return res
return wrapper # 返回函数名
@timmer
def foo():
time.sleep(3)
print('from foo')
foo()
高阶函数。。。。。下面的例子中foo就是属于一个高阶函数。
'''
高阶函数:
1、函数接收的参数是一个函数名
2、函数的返回值是一个函数名
只要满足其中一个就属于高阶函数
'''
def fun():
print("from fun")
def foo(fun1):
fun1()
foo(fun)
返回值是函数名的高阶函数
def fun():
print("from fun")
def foo(fun1):
return fun1
foo(fun)()
函数嵌套。。。。。。通过下面的例子,可以看出,函数内可以套函数,而函数也是一个变量,
通过locals()可以看到。
'''
函数嵌套
'''
def fun1():
print("from fun1")
def fun2():
print("from fun2")
print(locals())
fun1()
# 运行结果
#from fun1
#{'fun2': <function fun1.<locals>.fun2 at 0x000002A2C4D4AD90>}
闭包闭包,一个函数一个包。。。主要还是作用域,请看https://blog.csdn.net/June_King/article/details/87090970
重点来了。装饰器。。。。。。
# 简单的装饰器例子
def timer(func):
def wrapper():
func()
return wrapper
def test():
time.sleep(3)
print("test函数执行完毕")
res = timer(test)
res()
这是不对的,前面说过,装饰器不能修改被装饰函数的源代码,不能修改被装饰函数的调用方式。
这里调用时,修改了调用的方式。。。
那这样呢?
test = timer(test)
test()
看着是没有修改调用方式,但是每次调用时都会重新赋值。。。这样不合理
那应该怎么做?下面这样写,仅仅是在函数调用之前加上@装饰器名字即可
@timer
test()
看下面的例子,看看都打印了什么。
def timer(func):
def wrapper():
func()
return wrapper
@timer
def test():
time.sleep(2)
print("test函数执行完毕")
return "test()的返回结果"
res = test()
print(res)
可以发现,我们并没有得到test()函数的返回值,如果想要得到被装饰函数的返回值,需要这样写
def timer(func):
def wrapper():
res = func()
return res
return wrapper
在装饰器中通过变量来接收被装饰函数的返回值,然后利用return返回。这样一个带有返回值的装饰器就书写完成了。
这些还远远不够,有时候我们被修饰的函数还需要传入一些参数
def timer(func):
def wrapper(name, age):
res = func(name, age)
return res
return wrapper
@timer
def test(name, age):
time.sleep(2)
print("name:%s,age:%d," % (name, age))
print("test函数执行完毕")
return "test()的返回结果"
res = test('june', 18)
print(res)
上面的例子虽然可以传递参数,但依然存在不足,当test()的参数变化时,上面的例子就不能用了,需要对装饰器进行改进
def timer(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
return res
return wrapper
上面的这个例子可以实现无论被修饰函数的参数如何让改变,都能够接收。关于*args,**kwargs可以参考https://blog.csdn.net/June_King/article/details/87085052
好了,目前为止我们写的装饰器可以传入参数,也可以拥有返回值了,那么如果我们的装饰器还需要参数的话,那。。。。
def auth(filed):
print(filed)
def fun1(fun):
def fun2(*args, **kwargs):
fun(*args, **kwargs)
return fun2
return fun1
@auth("我是装饰器的参数")
def foo():
print("from foo")
foo()
在原来的基础上再加一层函数。。。
小结,不修改原函数代码,不修改原函数的调用方式。
python迭代器、生成器、装饰器之装饰器的更多相关文章
- Python迭代器生成器与生成式
Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- Python 迭代器&生成器
1.内置参数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice ...
- python 迭代器 生成器
迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- python迭代器,生成器,推导式
可迭代对象 字面意思分析:可以重复的迭代的实实在在的东西. list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定) 专业角度: ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- Python迭代器&生成器&装饰器
1. 迭代器 1.1 可迭代对象(Iterator) 迭代器协议:某对象必须提供一个__next__()方法,执行方法要么返回迭代中的下一项,要么引起一个Stopiteration异常,以终止迭代(只 ...
- Python迭代器,生成器,装饰器
迭代器 通常来讲从一个对象中依次取出数据,这个过程叫做遍历,这个手段称为迭代(重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值). 可迭代对象(iterable):是指该对象可以被 ...
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
随机推荐
- aiohttp 支持异步的网络请求模块
通常在进行网络数据采集时候我们会用到requests,urllib等模块,但是这些模块在使用中并不支持异步,所以今天我们介绍一个支持异步网络请求的模块aiohttp. 首先我们使用flask简单的搭一 ...
- Educational Codeforces Round 75 (Rated for Div. 2) B. Binary Palindromes
链接: https://codeforces.com/contest/1251/problem/B 题意: A palindrome is a string t which reads the sam ...
- HR#7 题解
T1 签到题 #include<bits/stdc++.h> #define R register int using namespace std; inline int g() { R ...
- Cogs 13. 运输问题4(费用流)
运输问题4 ★★☆ 输入文件:maxflowd.in 输出文件:maxflowd.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 一个工厂每天生产若干商品,需运输到销售部门进 ...
- Python的模块,模块的使用、安装,别名,模块作用域
模块和包 所谓的模块就是将不同功能的函数分别放到不同的文件中,这样不仅有利于函数的维护,也方便了函数的调用.在Python中,一个.py文件就是一个模块(Module). 在模块的上层有一个叫做包(P ...
- linux系列(二十三):df命令
1.命令格式 df [选项] [文件] 2.命令功能 显示指定磁盘文件的可用空间.如果没有文件名被指定,则所有当前被挂载的文件系统的可用空间将被显示.默认情况下,磁盘空间将以 1KB 为单位进行显示, ...
- css添加了原始滚动条要隐藏滚动条的显示
// 添加伪类 <style> ::-webkit-scrollbar {display:none} </style> <div style=" width:2 ...
- RBF、GRNN 和 PNN 神经网络在Matlab中的用法
一.RBF神经网络 RBF神经网络概述 径向基函数神经网络 与 BP 神经网络的区别在于训练过程--其参数初始化具有一定方法,并非随机,隐含层的末尾使用了径向基函数,它的输出经过加权和得到 LW2.1 ...
- OpenJudge 1.5.36:计算多项式的值
描述 假定多项式的形式为xn+xn-1+…+x2+x+1,请计算给定单精度浮点数x和正整数n值的情况下这个多项式的值. 输入输入仅一行,包括x和n,用单个空格隔开.x在float范围内,n <= ...
- Vue-cli 构建项目后 npm run build 如何在本地运行查看
当你在本地直接打开index.html 你会发现了一丢丢404,这时候你有两个办法解决问题: 1:改变路径为相对路径. 在config 文件夹中index.js的 build对象里, 把 assets ...