python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程

python装饰器[1]

首先先明白以下两点

#嵌套函数

defout1():definner1():print(1234)

inner1()#当没有加入inner时out()不会打印输出1234,当前层级也就是作用域下必须调用函数才能引用

out1()

#函数作用域

defout2():

a= 'aaa'

definner2():

a= 'bbb'

print(a)

inner2()print(a)

out2()#当相同变量处于不同嵌套函数中,会根据作用函数由内而外查找

装饰器:本质还是一个函数, 在不改变函数调用方式的情况下 对函数进行额外功能的封装,装饰一个函数 转给他一个其他的功能

装饰器的目的:装饰器的原本是用来在项目上线之后,因为已经上线了,大批量改代码的话很麻烦,由此产生了装饰器

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

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

importtimedefdemo():print("wo shi rainbol")deftime1():

start=time.time()

demo()#给time1函数增加了一个demo的功能

end =time.time()print(end-start)

time1()#这样方式很low,如果有一个添加n个函数添加此功能会很麻烦

importtimedefdemo():print("wo shi rainbol")defdemo2():print("wo yeshi rainbol")deftime1(fuc):

start=time.time()

fuc()#把之前的demo改成公用的fuc,函数即变量

end =time.time()print(end-start)

time1(demo)#通过调用time1方法,fuc赋值成了demo,再调用demo的方法

time1(demo2)#time1(demo。。)

以上完成了对任意函数改变调用方式进行了功能的封装,那如何用不改变调用方式的情况下对其进行功能的封装呢?

importtimedefdemo():print("wo shi rainbol")deftime1(fuc):def inner():#根据之前学过的嵌套函数,增加一层inner方法,把值放入其中

start =time.time()

fuc()

end=time.time()print(end-start)return inner#返回inner方法,但是没有运行

demo = time1(demo)#time1包含了inner的功能/拿到inner的返回值并且赋值给res,装饰器的目的是不改变变量名所以这边仍然用demo变量赋值

demo()#demo通过括号运行inner方法

#下面通过真正的装饰器可以省去上面的步骤

importtimedeftime1(fuc):#2.time1(demo),这里的fuc相当于形参,其实就是demo

definner():

start=time.time()

fuc()

end=time.time()print(end-start)returninner#3.返回inner函数,但没有执行哦

@time1#1.python先会整体浏览一遍代码关键字的代码,找到了demo方法上头有装饰

# 先调用装饰器,time1也就是demo = time1(demo),括号中的demo相当于实参

defdemo():print("wo shi rainbol")

# demo = time1(demo) <=====> @time1 去掉@time1在这家这段也是一样的

demo()#4.现在才执行()执行函数

#简单装饰器

importtimedefsimper(fuc):def inner(*args,**kwargs):

start=time.time()

fuc(*args,**kwargs)#增加的方法

end =time.time()print(end -start)returninner

@simper#demo = simper(demo)

def demo(name):#定义一个方法

print(name)#增加一个公用的功能点

demo(1)

#高级装饰器  当我们再原来装饰器的业务上再增加一个形参,来判断我们的业务是否符合指定的状态,这需要外面再套一层函数

importtimedefharder(type):if type == 1:defout(fuc):def inner(*args,**kwargs):

start=time.time()

fuc(*args,**kwargs)

end=time.time()print(end -start)returninnerreturnoutelif type == 2:pass@harder(1)#返回out函数

defdemo(name):print(name)

demo(1)

python装饰器[2]

装饰器与之间的迭代

下面是产品四次提出需求后再不修改调用参数使用装饰器在修改lose函数来完成我们业务上的需求,原因是上线项目许多接口都调用我们这个类下的参数,再不破坏接口本身情况下使用装饰器迭代是最佳选择

importtime#现在有一个需求1.0:在整个功能的基础上再添加一个减去4.5的操作使得最后结果为0,前提条件是不修改调用参数

defouter(fuc):def inner(*args, **kwargs):

a= fuc(*args, **kwargs) - 4.5

returnareturninner#迭代需求1.1:在整个功能的基础上再添加一个增加10的操作使得最后结果为10,提前条件是不修改调用参数

defouter2(fuc2):def inner2(*args, **kwargs):

b= fuc2(*args, **kwargs) + 10

returnint(b)returninner2#迭代需求1.2:在整个功能的基础上再添加一个时间参数判断lose函数的时间,目前为了模拟添加2秒延迟时间,提前条件是不修改调用参数

defshowtime(fuc):def inner3(*args, **kwargs):

starttime=time.time()

a= fuc(*args, **kwargs)

time.sleep(2)

endtime=time.time()

b= endtime -starttimereturna, breturninner3#迭代需求2.0:目前项目的lose的方法在业务繁忙时会异常中断,为此接口添加异常处理,提前条件是不修改调用参数

deftryexception(fuc):def tryer(self, *args, **kwargs):try:

res= fuc(self, *args, **kwargs)exceptException as e:

self.lose()return 'ERROR'

returnresreturntryer

'''主程序'''classMyDecorato(object):def __init__(self):pass

defchengxu(self, a, b):

c= a +breturnc

@tryexception#4.最后调用tryexception装饰器,装饰器之间调用是从下到上来依次调用

@showtime #3.调用showtime装饰器

@outer2 #2.调用outer2装饰器

@outer #1.先调用outer装饰器

deflose(self, c):#频繁调用的函数lose

pingjun= c / 2

returnpingjun

d=MyDecorato()

res1= d.chengxu(6, 3)

res2, time=d.lose(res1)print('最后的值:', res2, '时间:', time)

python装饰器[3]

#wrap函数为functools标准库中模块

deftest():'''i am test'''

print('一个简单的实验')

test()print(test.__doc__)print(test.__name__)#

#>> 一个简单的实验#>> i am test#>> test

print('--------------------------------')defouter(fuc):'''outer is me'''

print('this is outer')def inner(*args,**kwargs):'''inner is me'''

print('this is inner1')

fuc(*args,**kwargs)print('this is inner2')returninner

@outerdeftest():'''i am test'''

print('一个简单的实验')

test()print(test.__doc__)print(test.__name__)#>> this is outer#>> this is inner1#>> 一个简单的实验#>> this is inner2#>> inner is me#>> inner

print('-----------------------')#如果我们想要得到test里面的数据就要调用一个特定装饰器来帮我们实现

importfunctoolsdefouter(fuc):'''outer is me'''

print('this is outer')#@functools.wraps(fuc)

def inner(*args,**kwargs):'''inner is me'''

print('this is inner1')

fuc(*args,**kwargs)print('this is inner2')#return inner

return functools.update_wrapper(inner,fuc)#@functools.wraps(fuc)也可以,update_wrapper是调用其内部wrapper

@outerdeftest():'''i am test'''

print('一个简单的实验')

test()print(test.__doc__)print(test.__name__)#>> this is outer#>> this is inner1#>> 一个简单的实验#>> this is inner2#>>> i am test#>> test

print('------------------')#保持wrapper和test的属性值一样,这样也可以实现同样的效果

importfunctoolsdefouter(fuc):'''outer is me'''

print('this is outer')def inner(*args,**kwargs):'''inner is me'''

print('this is inner1')

fuc(*args,**kwargs)print('this is inner2')

inner.__doc__ = fuc.__doc__inner.__name__ = fuc.__name__

returninner

@outerdeftest():'''i am test'''

print('一个简单的实验')

test()print(test.__doc__)print(test.__name__)

python装饰器[4]

#通过类中的装饰器实现,普通方式

classFoo(object):def __init__(self):pass

defdecorator(foo):definner(self):print('before')

foo(self)print('after')returninner

@decoratordeftest(self):print('testing')

foo=Foo()

foo.test()

#通过类中的装饰器实现,继承方式

classFoo(object):def __init__(self):pass

defdecorator(self):def inner(*args, **kwargs):print('before')

self(*args, **kwargs)print('after')returninner

@decoratordeftest1(self):print('我被执行了')classFoo2(Foo):

@Foo.decorator#执行被继承的方法

defdecorator(self):print('执行被继承的方法开始')

super(Foo2, self).test1()#运行Foo2父类Foo的test1方法

print('执行被继承的方法结束')

foo=Foo()

foo.test1()print('-----')

foo2=Foo2()

foo2.decorator()

#实例

classTest1(object):defdecorator1(self):def inner(*args, **kwargs):

self(*args, **kwargs)print('n年前添加的附加功能')returninner

@decorator1deftest1(self):print('n年前实现的某个功能')classTest2(Test1):defdecorator2(self):def inner(*args, **kwargs):

self(*args, **kwargs)print('今天添加的附加功能')returninner

@decorator2deftest2(self):

super(Test2, self).test1()print('昨天自己实现的功能')

foo=Test2()

foo.test2()

View Code

#通过类中的装饰器实现,获取对象方法的实例属性defmod_test(cls):#返回修改的类

defdecorator(fun):#返回装饰函数

defnew_fun(self):print(self.before)print(fun(self))print(self.after)returnnew_fun

cls.test=decorator(cls.test)returncls

@mod_testclassFoo(object):def __init__(self):

self.before= "before"self.after= "after"

deftest(self):return "testing"foo=Foo()

foo.test()

python迭代器

l = [1,2,3,4,5,6]print(l.__iter__()) #iter(l)这两者是一样的,都返回了一样迭代器对象

d =(iter(l))print((next(d)))#返回 1

print((next(d)))#返回 2#所以生成器本身就是迭代器

#for循环本身主要做的三件事:

for i in [1,2,34,5,5]:#1.

iter([1,2,34,5,5])#调用可迭代对象的iter方法返回一个迭代器对象#2.调用迭代器对象的next方法#3.处理Stoplteration

#校验

from collections importIterator,Iterable#Iterable 迭代器#Iterator 迭代对象

print(isinstance([1334],list))#判断给对象是否为一个list,返回布尔值

print(isinstance(l,Iterable))#判断是否是迭代对象,返回布尔值

自定义迭代器

classMytest:def __init__(self, len):

self.index=0

self.len=lendef __iter__(self):returnselfdef __next__(self):if self.index

self.index+= 1

returnself.indexraiseStopIterationfor i in Mytest(20):print(i)#打印1-20,迭代器底层调用,结构复杂

python生成器

用法1:

f = (x for x in range(1000))#使用列表生成式外面套了一层中括号并赋值给f对象

print(f)#此时f打印的就是一个生成器对象 at 0x0000000001DD79E8>#此时需要打印x必须如下方式,生成器就像一位厨师,做出x就是一盘盘菜,每一盘菜必须吃完再吃第二盘,而且不能跳着吃,倒着吃

print(next(f))#调用使用next()比较常见

print(next(f))print(next(f))print(f.__next__())#f.__next__()也是可以的 py2的调用方式是f.next直接调用

print(f.__next__())print(f.__next__())

用法2:

#yield也是生成器中的例子,如果在没有使用next(),函数根本不会被执行,调用每一次程序会检测yield如果有,yield包括后面的代码不会执行,直到下次调用才执行下次的,所以函数中只要有yield就是生成器#yield可以理解成return

deftest(len):print(len,'11')yield 1

print(len,'222')yield 2

print(len,'333')

test('1')#此函数不会被调用

for i in test('1'):#for内置有生成器next,可以对生成器对象一直使用next(n)

print(i,'调用')#打印#1 11#1 调用#1 222#2 调用#1 333#这个就是异步io的原理了,python里面的协程基于yield实现

#生成器的好处:#如果我们写一个 danger = [x for x in range(9999999999999999999)]#当我们打印danger时我们的电脑会在内存中放置0-n的数据,造成内存不足,死机的情况,生成器的出现会把旧变量替换成新变量,从而不会造成大数据所产成内存泄露的问题

nodanger = (x for x in range(999999999999999999999999))print(next(nodanger))

协程

简单的说只要能够完成多任务切换的都是协程,规避io操作是协程体现出的效果

yield是协程最底层的使用方法

#yield的使用

deff():print('jjjj')yield 1

print('gggg')yield

print(f())#创建一个生成器对象,但是函数不会执行

gen=f()#next(gen)#执行生成器对象

gen.send(None)

x= gen.send(10)#next(gen)这两者是一样的

print(x)

gevent模块

#gevent模块 在gevent中主要模式就是greenlet,它是c扩展的轻量级协程

from greenlet importgreenletdeftest1():print('111')

b.switch()print('333')

b.switch()deftest2():print('222')

a.switch()print('444')

a= greenlet(test1)#创建一个生成器对象

b =greenlet(test2)

a.switch()

#from gevent import monkey#monkey.patch_all()#实时监听io堵塞,效果显著,要注意的是这两句话要放到最上面不然就会报错,我也不知道为什么

importgeventdeftest3():print('模拟io堵塞1')

gevent.sleep(1)#模拟堵塞时间

print('堵塞消除1')deftest4():print('模拟io堵塞2')

gevent.sleep(2)print( '堵塞消除2')

gevent.joinall([gevent.spawn(test3),gevent.spawn(test4)])#joinall效果是如果两个方法中其中一个出现io堵塞,会跳到另外一个方法,如果都堵塞都会等着,直到io堵塞消除#优势:io堵塞的时间取决于io堵塞最长的时间,提升效率

协程实例:

from gevent importmonkey

monkey.patch_all()

#gevent模块  #基于greenlet封装,避免多线程切换导致io执行效率降低

importgeventimportrequestsdefrun(name, url):

r=requests.get(url)

open(name+ '.html', 'wb').write(r.content)

url= {'rainbol01': 'https://www.cnblogs.com/RainBol/','rainbol02': 'https://www.cnblogs.com/RainBol/p/9505438.html','rainbol03': 'https://www.cnblogs.com/RainBol/p/10077388.html'}for name, url inurl.items():

g= gevent.spawn(run, name, url) #启动

g.join() #等待并切换

#阻塞等待分配任务完成后结束#l = []#for i in range(10):#g = gevent.spawn(run,name,url)#l = g.append(g)#g.joinall(l)

版权声明:本文原创发表于 博客园,作者为 RainBol本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/559406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jni c 传递对象到java_JNI将二进制数据从C传递到Java

我需要帮助将二进制数据传递给Java.我正在尝试使用jbytearray但是当数据进入Java时它看起来很糟糕.有人可以帮我一把吗&#xff1f;这是一些示例代码的片段.首先是原生C面&#xff1a;printf("Building audio array copy\n");jbyteArray rawAudioCopy env->NewBy…

python查看电脑配置_怎么查看电脑配置(教你如何查看电脑配置信息和型号)

如今&#xff0c;由于游戏、影音、学习或者工作的需要&#xff0c;用户都会有购买电脑的时候&#xff0c;不过对于一些不懂电脑的小白来说&#xff0c;如果连电脑配置都不会差的话&#xff0c;是十分容易被宰的。比如组装台式机的时候&#xff0c;可能一个不注意就被JS调包了&a…

mysql gtid深入_深入理解MySQL 5.7 GTID系列(四):mysql.gtid_executedPREVIOUS GTID EVENT

之所以把MySQL.GTID_EXECUTED表的作用和PREVIOUS GTID EVENT的改变放到一起进行描述是因为它们后面文章探讨的基础。这部分使用到了我自己使用C语言写的原生BINLOG解析工具INFOBIN。一、GTID EVENT为什么要先描述什么是GTID EVENT呢&#xff1f;因为后面会用到&#xff0c;实际…

mysql 回滚段_MySQL和PostgreSQL比较

1、MySQL相对来说比较年轻&#xff0c;首度出现在1994年。它声称自己是最流行的开源数据库。MySQL就是LAMP(用于Web开发的软件包&#xff0c;包括 Linux、Apache及Perl/PHP/Python)中的M。构建在LAMP栈之上的大多数应用都会使用MySQL&#xff0c;包括那些知名的应用&#xff0c…

java应用程序多态_java – 多态和n层应用程序

这是一个很好的问题.这里有不止一个似是而非的方法;你必须平衡权衡,做出适合你情况的选择.(1)有些人会认为Document接口应该为实例提供一个自己呈现的方法.这从OO的角度来看是有吸引力的,但是根据您的观点技术,加载您的具体文档类(可能是简单的域模型类),具有JSP,Swing组件或其…

支持向量机python实例_Python机器学习SVM简单应用实例 | kTWO-个人博客

1、前言在上一篇理论性的文章中我们说过了&#xff0c;SVM是分线性可分和线性不可分两种情况的&#xff0c;线性可分的比较容易理解&#xff0c;比较容易一些&#xff0c;线性不可分的就稍微复杂一点了。我们测试就分别用线性可分和线性不可分两种情况分别测试Python中的SVM算法…

dbscan java_DBSCAN算法的Java,C++,Python实现

最近由于要实现‘基于网格的DBSCAN算法’&#xff0c;网上有没有找到现成的代码[如果您有代码&#xff0c;麻烦联系我]&#xff0c;只好参考已有的DBSCAN算法的实现。先从网上随便找了几篇放这儿&#xff0c;之后对比研究。DBSCAN简介&#xff1a;1.简介DBSCAN 算法是一种基于密…

python云计算主要是干嘛的_国内python 云计算是干什么的

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":6,"count":6}]},"card":[{"des":"云服务器 ECS(Elastic Compute Service)是一…

python画pr曲线代码_Yolov3测试图及绘制PR曲线,yoloV3,map,和,画

训练指令&#xff1a;./darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 | tee train_yolov3.logps&#xff1a;For training with mAP (mean average precisions) calculation for each 4 Epochs (set validvalid.txt or train.txt in obj.data fil…

xampp 支持pdo mysql_在Windows上安装PHP PDO(xampp)

我正在尝试开发一个可以在PHP上连接到尽可能多的不同数据库的Web应用程序. PDO(http://www.php.net/manual/en/book.pdo.php)似乎是正确的界面,但我无法安装所需要的所有不同PDO数据库驱动程序所需的扩展.请注意,我在Windows 7机器上使用xampp. PHP版本5.3.8. PDO驱动启用了Mys…

python常用的库有哪些餐厅_这十个Python常用库,学习Python的你必须要知道!

想知道Python取得如此巨大成功的原因吗&#xff1f;只要看看Python提供的大量库就知道了包括原生库和第三方库。不过&#xff0c;有这么多Python库&#xff0c;有些库得不到应有的关注也就不足为奇了。此外&#xff0c;只在一个领域里的工作的人并不知道另一个领域里有什么好东…

java将图片转byte存入数据库_Java将byte[]转图片存储到本地的案例

Java中&#xff0c;将字节数组转成图片的有很多种方式&#xff0c;今天在这里记录其中一种&#xff0c;方便以后查询&#xff0c;也可以提供给没有接触的童鞋做一个参考。首先是将图片转成字节数组import sun.misc.BASE64Encoder;import java.io.*;// 传入图片路径&#xff0c;…

python高阶函数看不懂_Python进阶:高阶函数的详细说明

这篇文章讲述了Python进阶&#xff1a;高阶函数的详细说明有需要的朋友可以参考函数式编程函数是Python内建支持的一种封装&#xff0c;我们通过把大段代码拆成函数&#xff0c;通过一层一层的函数调用&#xff0c;就可以把复杂任务分解成简单的任务&#xff0c;这种分解可以称…

java callable接口_Java多线程之Callable接口的实现有返回值的线程

import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;//在主线程获取callable线程返回值时&#xff0c;如果callable线程还存在线程没有执行完&#xff0c;则主线程…

python聊天软件实现_python实现点对点聊天程序

用Python实现点对点的聊天&#xff0c;2个程序&#xff0c;一个是client.py&#xff0c;一个是server.py&#xff0c;通过本机地址127.0.0.1连接进行通信&#xff0c;利用多线程把发送消息和接收消息分开独立进行。client代码&#xff1a;import socketimport sysimport thread…

java编译器代码检查_Java编译器可以优化此代码吗?

我拥有的Java 8编译器似乎并没有对其进行优化.编译后使用“ javap -c”检查字节码&#xff1a;public static void main(java.lang.String[]);Code:0: new #2 // class java/util/Random3: dup4: invokespecial #3 // Method java/util/Random."":()V7: invokevirtua…

python中rgb_python - 图像的RGB矩阵

Taking an image as input, how can I get the rgb matrix corresponding to it?I checked out the numpy.asarray function. Does that give me the rgb matrix or some other matrix?解决方案The simplest answer is to use the NumPy and SciPy wrappers around PIL. Ther…

java volatile lock_Java并发学习笔记 -- Java中的Lock、volatile、同步关键字

Java并发一、锁1. 偏向锁1. 思想背景来源&#xff1a;HotSpot的作者经过研究发现&#xff0c;大多数情况下&#xff0c;锁不仅不存在多线程竞争&#xff0c;而且总是由同 一线程多次获得&#xff0c;为了让线程获得锁的代价更低而引入了偏向锁。原理&#xff1a;在对象头和栈帧…

python 数组赋值_pythonamp;numpy的赋值

有点编程基础的童鞋看到这个标题可能会有点懵逼&#xff0c;这还是个问题吗&#xff1f;不就是个等号()解决问题嘛&#xff01;我也希望是如此简单&#xff0c;因为上个星期被这个问题折磨到崩溃&#xff01;一般的python程序需要赋值时的确是通过等号()实现的&#xff0c;不管…

java字符串匹配dp_[OI]字符串DP小结

顾名又思义&#xff0c;是在字符串上进行的DP操作。因为字符串本身可以看作是一个序列&#xff0c;所以有些时候字符串DP可以用区间DP来解决。P2246 SAC#1 - Hello World(升级版)题目描述在讲义的某一面&#xff0c;他看见了一篇文章。这篇文章由英文字母(大小写均有)、数字、和…