python第五天:协程,匿名函数,递归函数,模块导入,re模块

上节回顾

函数对象

函数可以被当成数据来传递

def func():

pass

1.可以被引用。f=fun

2.可以当做参数传递给另外一个函数

3.可以作为函数的返回值

4.可以当做容器类型的元素

比如用户有10多个参数,我们不需要写10多个if判断。可以写一个字典。

dic = {‘func1’:func1,’func2’:func2}

调用个时候就用dic[‘func1’]()

函数的嵌套

函数的嵌套可以分为两种:嵌套定义和嵌套调用。

嵌套调用:函数的执行过程中调用其他的函数,可以更加细化的功能。

嵌套定义(在定义函数时,又使用def关键字定义了其他函数):我们可以在闭包函数和装饰器里面用到他。

名称空间和作用域

内置名称空间(py解释器运行了就定义了这个空间)

全局名称空间(文件执行的时候定义这个空间,别的文件调用需要import这个变量)

局部名称空间(函数调用的时候,函数执行完就释放了)

全局作用域:全局有效,在任何位置都能被访问到,存活到文件执行结束。

局部作用域:局部有效,只能在函数内部被访问到,在函数执行结束后,就释放了。

闭包函数

是一个定义在函数内部的函数,不受外界变量影响,调用外面的函数,直接返回闭包函数对象。

def f1():

def f2():

print(x)

return f2

f=f1()

f()

装饰器

函数对扩展是开放的,对修改是封闭的。为了满足这个特性就用到了装饰器。

装饰器本身可以是任意可调用对象,可以装饰任意可调用对象。

装饰器要遵循的原则:

1、不修改被装饰对象的源代码

2、不修改被装饰对象的调用方式(包括返回值,参数)

迭代器

迭代:重复上一次过程,每一次重复都基于上一次执行的结果而继续进行。

可迭代对象:有__iter__方法的就叫可迭代对象。

迭代器对象:有__next__方法的就是迭代器对象。

为何要有迭代器:提供了一种不依赖于索引的迭代方式。

迭代器的优缺点:提供一种不依赖于索引的迭代方式、节省内存。

无法获取长度,一次性的,只能取下一个。

生成器

函数体内含有yield关键字,该函数执行的结果就是生成器。

生成器本质就是迭代器,所以yield的功能就是:

1.把函数的执行结果做成迭代器。

2.yield相当于可以在函数里面写多个的return。

3.生成器可以通过send方法给yield赋值,然后yield再给别的变量赋值。

比如 num=yield 3

y=x.send(10)

那num就是10,y就是3。

上课内容

协程函数

协程函数就是给生成器传送参数,让每次迭代过程都根据这个参数传送不同的结果。

yield可以往函数内传值。

def eater(name):

print(“ready to eat”%name)

while True:

food = yield

print(“start to eat ”%food)

g=eater(‘alex’)

next(g)

g.send(‘苹果’)

生成器的开始必须要传送的NONE。

可以用装饰器来生成一个不需要传NONE的。

def zhuangshi(fun):

def fun1(*args,**kwargs):

f = fun(*args,**kwargs)

f.send(None)

return f

return fun1

@zhuangshi

def eater(name):

print("ready to eat%s"%name)

food_list=[]

while True:

food_list.append(food)

food = yield food_list

print("%s start to eat %s"%(name,food))

g=eater(‘alex‘)

g.send(‘苹果‘)

总结:yield不光有return的功能,可以通过shengcheng.send()函数给他传参数。同时也可以返回yield后面的值。

面向过程的编程方法

1.编写一个能返回程序,并且将

os.walk用法

传入一个目录,返回一个元组,里面有3个元素。(父目录,子目录列表,子文件列表)

然后对其下面的子目录递归的执行walk,返回多个元组。

类似这种情况:

我们可以通过编写多个函数生成器彼此嵌套:找到文件名→打开文件→找到行→判断行→打印文件名这个过程来写一个和grep -rl类似的程序。

这种程序是一个类似流水线式的编程思路,是机械式的。

优点:程序结构清晰,可以把复杂的问题简单化。缺点是扩展性差,牵一发而动全身。

匿名函数lambda

我们把函数

def f1(x,y):

z=x+y

return z

改写成匿名函数,首先用lambda替换def ,去掉f1(),将函数主体和return替换成:即可,将z写成x+y。

lambda x,y:x+y

一些能用到匿名函数的内置

map:map

reduce

filter

max(salaries,key=func):将前面的结果传给后面的函数作为一个参数,然后将返回的结果来进行max的比较。不过返回的值的类型是直接max前面的值的类型。

高阶函数:如果函数的一个参数是一个函数,或者返回的是一个函数,那他就是高阶函数。

map:传送两个参数,第一个参数是一个函数对象,后面你的是一个可迭代对象。

map(lambda x:x+’sb’,list)

他会一次for循环后面的对象,然后传给前面的fun,然后他会将处理过的东西插入到新的map对象(可以理解为列表)中,最后返回这个MAP函数。

reduce:传三个参数,函数,可迭代对象,初始值。

如果你不给初始值,他会把可迭代对象的第一个值作为初始值,然后迭代后面的东西,把他和初始值赋给前面的函数得到结果作为结果和继续迭代的东西进行操作。

filter:传两个参数,第一个参数?一个函数,第二个参数是一个可迭代对象。

filter (lambda x:x.endswith(‘SB’),l)

递归函数:在函数的调用过程中,直接或间接调用了函数本身,这就是函数的递归调用。

python里面有一个递归锁。默认可以递归1000层

可以用

来设。

递归函数分为两个过程:递推和回溯。

递归的注意事项:

1.递归必须有一个明确的结束条件。

2.每次进入更深一层递归的时候,问题规模相比上次递归都应该有所减少。

3.递归效率不高,在python中递归层数过多会导致栈溢出。

递归的应用:

二分法

模块:自带模块、自己写的模块、第三方模块。

如何使用模块:

1、import

2、

导入模块做的事情:

1、产生新的名称空间

2、以新建的名称空间为全局名称空间,执行文件的代码

3、拿到了一个模块名,指向了spam.py。

还有一种方式导入:

from 导入

这个也是一个模块导入:

1.产生新的名称空间。

2.以新的名称空间为全局名称空间,执行文件的代码。

3.直接拿到spam.py产生的名称空间的名字

4.会跟当前文件的变量冲突

from导入的方式就是比import调用的方便一点。

执行导入的方法,还是以原文件的变量为准。

from spam import *(直接导入所有的变量)

直接导入模块内的__all__列表里面的所有定义的变量。

__name__:当做脚本执行,他的值是__main__,被当做模块导入的时候__name__=spam。

所以一般文件最下面都是

这样就是被当做模块导入的时候就不会执行,而自己测试模块的时候就可以在下面弄。

import的搜索路径:

先找内存→然后找内置→然后找sys.path。

我们可以自己添加sys.path的东西。

sys.path.insert(0,r’C:\.....’)

导入包:

1.无论是import形式还是from...import形式,凡事在导入语句中遇到带点的,就要知道,这是关于包才有的导入语法。

点的左边必须是一个包,右边有可能是包也有可能是模块。

import 包的话就是相当于导入了glance下的__init__.py

调用包的话就相当于是在调包下面的init文件。

绝对导入:导入包的时候 在glance下的__init__下面使用from glance.xx import xxx

这样 和glance一级的文件就可以直接找这个包。

from ..db import xxxx

from ...db import xxx

使用相对路径是为了方便以后包名字更改的问题。

*的特殊用法

可以直接导入模块。这是另外一种用法。

RE模块:

导入re模块,import re

正则的在线调试工具:tool.oschina.net/regex/

re.findall(partten,str)

元字符:

\w:匹配字母数字及下划线。

.可以匹配任意字符,但是没法匹配换行符\n

[]:匹配其中任意一个字符,可以匹配\n。

这里的?是转义的意思,不是0-1次,是将贪婪匹配转换为非贪婪匹配。

|:

匹配成功了只会返回括号里面的内容。

这样转义一下就好了。

下面这个例子同理:

时间: 2024-10-07 18:44:01

python第五天:协程,匿名函数,递归函数,模块导入,re模块的相关文章

Python异步IO之协程(一):从yield from到async的使用

引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中均存在一些缺点.因此,我们引出了协程. Tips 欲看完整代码请见:我的GitHub 为什么需要协程?首先,我们需要知道同步和异步是什么东东,不知道的看详解.简单来说:[同步]:就是发出一个“调用”时,在没有得到结果之前,该“调用”就不返回,“调用者”需要一直等待该“调用”结束,才能进行下一步工作.

python 高性能编程之协程

用 greenlet 协程处理异步事件 自从 PyCon 2011 协程成为热点话题以来,我一直对此有着浓厚的兴趣.为了异步,我们曾使用多线程编程.然而线程在有着 GIL 的 Python 中带来的性能瓶颈和多线程编程的高出错风险,"协程 + 多进程"的组合渐渐被认为是未来发展的方向.技术容易更新,思维转变却需要一个过渡.我之前在异步事件处理方面已经习惯了回调 + 多线程的思维方式,转换到协程还非常的不适应.这几天我非常艰难地查阅了一些资料并思考,得出了一个可能并不可靠的总结.尽管这个

python并发编程之协程

阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长 ps:在介绍进程理论时,提

python并发编程之---协程

1.什么是协程 协程:是单线程下的并发,又称微线程,纤程. 协程是一种用户态的轻量级线程,协程是由用户程序自己控制调度的. 2.需要注意的点: 需要强调的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) #2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关) 对比操作系统控制线程的切换,用户在单线程内控制协程的切换 优点

Python并发实践_02_协程

python中实现并发的方式有很多种,通过多进程并发可以真正利用多核资源,而多线程并发则实现了进程内资源的共享,然而Python中由于GIL的存在,多线程是没有办法真正实现多核资源的. 对于计算密集型程序,应该使用多进程并发充分利用多核资源,而在IO密集型程序中,多核优势并不明显,甚至由于大多数时间都是在IO堵塞状态,多进程的切换消耗反而让程序效率更加低下. 而当需要并发处理IO密集型任务时,就需要用到协程(Coroutine).协程并没有系统级的调度,而是用户级的调度方式,避免了系统调用的开销

python学习道路(day11note)(协程,同步与异步的性能区别,url爬网页,select,RabbitMq)

1.协程 1 #协程 又称微线程 是一种用户的轻量级线程 程序级别代码控制 就不用加机器 2 #不同函数 = 不同任务 A函数切到B函数没有进行cpu级别的切换,而是程序级别的切换就是协程 yelied 3 4 #单线程下多个任务流用协程,比如打电话可以切换,nginx 5 #爽妹给你打电话的时候,她不说话,刘征电话过来时候你可以切过去,这时候要是爽妹说话,就会bibi响 6 ''' 7 8 协程的好处: 9 无需线程上下文切换的开销 10 无需原子操作锁定及同步的开销 11 "原子操作(ato

python简单线程和协程学习

python中对线程的支持的确不够,不过据说python有足够完备的异步网络框架模块,希望日后能学习到,这里就简单的对python中的线程做个总结 threading库可用来在单独的线程中执行任意的python可调用对象.尽管此模块对线程相关操作的支持不够,但是我们还是能够用简单的线程来处理I/O操作,以减低程序响应时间. from threading import Thread import time def countdown(n): while n > 0: print('T-minus:

Python的线程&进程&协程[0] -> 基本概念

基本概念 / Basic Concept 0 简介与动机 / Why Multi-Thread/Multi-Process/Coroutine 在多线程(multithreaded, MT)编程出现之前,计算机程序的执行是由单个步骤序列组成的,该序列在主机的CPU中按照同步顺序执行.即无论任务多少,是否包含子任务,都要按照顺序方式进行. 然而,假定子任务之间相互独立,没有因果关系,若能使这些独立的任务同时运行,则这种并行处理方式可以显著提高整个任务的性能,这便是多线程编程. 而对于Python而

Python并发编程:协程介绍

一 引子 基于单线程来实现并发,即只用一个主线程(很明显可利用的CPU只有一个)情况下实现并发,先回顾一下并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其它的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中第二种情况并不能提升效率,只是让CPU能够雨露均沾,实现看起来所有任务

python之并发编程—协程

引子 之前我们学习了线程.进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把cpu的利用率提高很多了.但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程.创建线程.以及管理他们之间的切换. 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发.这样就可以节省创建线进程所消耗的时间. 为此我们需要先回顾下并发的本质:切换+保存状