Python中的装饰器,迭代器,生成器
1. 装饰器
- 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
- 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
- 装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
- 开放封闭原则:对修改封闭,对扩展开放
import timedef timmer(fun):start_time=time.time()fun()end_time=time.time()def fun1():print("in func1")timmer(fun1) #改变了原先函数的执行
就要用闭包来包装此函数
import timedef timmer(fun):def inner():start_time=time.time()fun()end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用def fun1():print("in func1")print(timmer(fun1)) #可以运行,其实就是执行Inner,目的就是在全局可以调用,
fun1=timmer(fun1) #函数本身就是变量,变量值互换
fun1()
这样最基本的装饰器就完成了,Python为我们提供了语法糖,一个完整的装饰器如下:会允许函数传参并且返回值不变
import timedef timmer(fun):def inner(*args,**kwargs):start_time=time.time()ret = fun(*args,**kwargs)end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return retreturn inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用@timmer
def fun1(num):print("in func1 {}".format(num))return 123# print(timmer(fun1)) #可以运行,其实就是执行Inner,目的就是在全局可以调用,
# fun1=timmer(fun1) #函数本身就是变量,变量值互换
print(fun1(1))
这样可以修饰多个函数,但是要批量更改该怎么,如果不想装饰了,需要挨个去掉吗
import timedef outer():Flag=Falsedef timmer(fun):def inner(*args,**kwargs):if Flag:start_time=time.time()ret = fun(*args,**kwargs)end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return retelse:ret = fun(*args, **kwargs)return retreturn inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用return timmer @outer() #之所以加执行就是把outer的返回值timmer函数的内存地址放在这里,其实就是@timmer
def fun1(num):print("in func1 {}".format(num))return 1@outer()
def fun2(num):print("in func2 {}".format(num))return 2@outer()
def fun3(num):print("in func3 {}".format(num))return 3print(fun1(1))
print(fun2(2))
print(fun3(3))
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
使用小知识点eval
login_status={"user":None,"status":False}def outer():Flag=Truedef auth(func):def inner(*args,**kwargs):if Flag:with open("user.txt",encoding="utf-8") as read_f:if login_status['user'] and login_status['status']:ret = func(*args, **kwargs)return retuser_info=eval(read_f.read())name=input("your name>>:").strip()password=input("your password>>:").strip()if name in user_info and user_info[name]["password"] == password:login_status["user"]=namelogin_status["status"]=Trueprint(login_status)ret = func(*args,**kwargs)return retelse:print("bad")else:ret = func(*args, **kwargs)return retreturn innerreturn auth@outer()
def fun1():print("in func1")return 1@outer()
def fun2():print("in func2")return 2@outer()
def fun3():print("in func3")return 3fun1()
fun2()
fun3()
多个装饰器装饰同一个函数
def wrapper1(func):def inner():print('wrapper1 ,before func')func()print('wrapper1 ,after func')return innerdef wrapper2(func):def inner():print('wrapper2 ,before func')func()print('wrapper2 ,after func')return inner@wrapper2
@wrapper1
def f():print('in f')f()
结果原因如下:从后分析
装饰器小练习:
#编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
import time
from urllib.request import urlopendef wrapper(func):def inner(*args,**kwargs):start_time=time.time()ret = func(*args,**kwargs).decode('utf-8')end_time=time.time()print("{} time is {}".format(*args,end_time-start_time))return retreturn inner@wrapper
def get(url):return urlopen(url).read()# print(get('http://www.baidu.com'))
get('http://www.baidu.com')
2. 迭代器
其实迭代就是我们说的,可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代。
- 可迭代协议的定义非常简单,就是内部有了__iter__方法。
from collections import Iterablel = [1, 2, 3, 4]
t = (1, 2, 3, 4)
d = {1: 2, 3: 4}
s = {1, 2, 3, 4}print(isinstance(l, Iterable))
print(isinstance(t, Iterable))
print(isinstance(d, Iterable))
print(isinstance(s, Iterable))
print(dir([1,2]))
用__next__也可以遍历,不依赖for循环
l=[1,2,3,4]
l_iter=l.__iter__() #先把可迭代对象变成迭代器
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
while..try..
l=[1,2,3,4]
l_iter=l.__iter__() #先把可迭代对象变成迭代器
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值while True:try:item = l_iter.__next__()print(item)except StopIteration:break
3. 生成器
一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值
但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。
每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
生成器有什么好处呢?就是不会一下子在内存中生成太多数据
def genrator_fun1():a=1yield ab=2yield bg=genrator_fun1()
print(next(g))
print(next(g))
#生成器监听文件输入的例子
转载于:https://www.cnblogs.com/so-cool/p/8916225.html
Python中的装饰器,迭代器,生成器相关推荐
- Python中的装饰器、迭代器、生成器、推导式、匿名函数和高阶函数
文章目录 装饰器 迭代器 生成器 推导式 匿名函数 高阶函数 装饰器 闭包 介绍装饰器前先了解一下闭包,在Python中,一切皆对象(Object),函数(Function)也不例外,也是一个普通的对 ...
- [转载]理解PYTHON中的装饰器
[翻译]理解PYTHON中的装饰器 来源stackoverflow上的问题 链接 python的函数是对象 要理解装饰器,首先,你必须明白,在python中,函数是对象. 这很重要. 简单例子来理解为 ...
- python装饰器原理-python 中的装饰器及其原理
装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...
- python类装饰器详解-python 中的装饰器详解
装饰器 闭包 闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包. def decorator(p ...
- python中的装饰器decorator
python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x):return ...
- python编写装饰器_写python中的装饰器
python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) 1 de ...
- python中的装饰器(基础装饰器)
文章目录 一 前置知识-高阶函数,闭包 1. 高阶函数 2. 闭包 二 函数装饰器 1. 什么是装饰器(原理)? 2. 装饰器的实现 3. 何时执行装饰器 4. wraps方法 三 类装饰器 一 前置 ...
- 为什么说想到Python中的装饰器是天才
为什么说想到Python中的装饰器是天才 只需一个@符号就能分析.测试和重复使用你的代码 带着魔杖的仙女在Python代码中飞舞 软件中有没有什么是神奇的小魔法? 有,装饰器却非常接近! 如果说有一件 ...
- python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程
python装饰器[1] 首先先明白以下两点 #嵌套函数 defout1():definner1():print(1234) inner1()#当没有加入inner时out()不会打印输出1234,当 ...
最新文章
- java旅游系统项目经验_谁能跟我介绍一下Java 项目经验,刚进入这个行业。
- pgrouting进行路径规划之入门二
- 【HDU2683 TCE-frep number system 完全数+二项展开式】
- 你在做大数据?你有目标么?
- CVPR 2021 | Facebook提出FP-NAS:搜索速度更快、分类精度更高、性能更好
- POJ2195 Going Home 最小费用最大流
- 关于自然语言处理,有一本通关手册待接收
- 【SICP练习】79 练习2.51
- 最长递增子序列 子串_最长递增奇偶子序列
- 一步步学习NHibernate(8)——HQL查询(2)
- PS 2022,PR 2018,AE 2017【百度网盘链接,没套路】
- PocketPC常用程序和设置打开命令参数列表
- [javascript]Ex站阅读器
- 使用wireshark抓取聊天信息与爬虫入门
- centos7.X系统初始化脚本
- 大学c语言作业用什么搜题比较好,快速查找题库_什么手机软件可以把题库输入进去然后输入关键字可以查找点道题_淘题吧...
- 不一样的技术人工作、面试指南
- 等腰杨辉三角C语言实现
- 空调压缩机常见故障与检修
- JASS代码加翻译更新(第四篇)