python中协程与函数的区别_Python基础(协程函数、内置函数、递归、模块和包)

写在前面

凭着爱,再回首;

一、协程函数(生成器:yield的表达式形式)

1.yield 的语句形式: yield 1

- 这种方式在 Python基础(函数部分)-day04 里面详细介绍过,这里不再赘述;

2.yield 的表达式形式: x=yield

- 示例1:使用 next() 方法调用生成器执行,没有给yield传值;

1 defdeco(func): # 定义了一个装饰器2 def wrapper(*args,**kwargs):3 res = func(*args,**kwargs)4 next(res) # 就是为了先执行一下 next方法5 returnres6 returnwrapper7

8 @deco9 defeater(name):10 print('%s ready to eat' %name)11 whileTrue:12 food=yield

13 print("%s start to eat %s" %(name, food))14 g = eater('alex') # 得到一个生成器函数15 next(g) # 第一次调用 生成器的next方法;(装饰器里提前执行了一次 next方法)16 next(g) # 第二次调用...17

18 ---

19 alex ready to eat # 装饰器里调用 next() 的打印结果20 alex start to eat None # 第一次调用 next() 的打印结果21 alex start to eat None # 第二次调用...

- 示例2:使用 send() 方法调用生成器执行,并给yield传值;

1 defdeco(func):2 def wrapper(*args,**kwargs):3 res = func(*args,**kwargs)4 next(res)5 returnres6 returnwrapper7

8 @deco9 defeater(name):10 print('%s ready to eat' %name)11 food_list =[]12 whileTrue:13 food=yield

14 food_list.append(food)15 print("%s start to eat %s" %(name, food))16 print("%s have eaten: %s" %(name,food_list))17 g = eater('alex')18 g.send('tomato')                    # 第一次调用生成器执行,传入 'tomato' 给 yield,然后由yield赋值给food变量;然后向下执行进入下一次while循环,暂停并等待;19 g.send('potato')20 g.send('beef')21 g.send('rice')22

23 ---

24 alex ready to eat25 alex start to eat tomato26 alex have eaten: ['tomato']27 alex start to eat potato28 alex have eaten: ['tomato', 'potato']29 alex start to eat beef30 alex have eaten: ['tomato', 'potato', 'beef']31 alex start to eat rice32 alex have eaten: ['tomato', 'potato', 'beef', 'rice']

注意:next(g) #等同于 g.send(None);

3.yield表达式形式的应用

1 #!/usr/bin/python

2 #-*- coding:utf-8 -*-

3

4 #实现Linux下的如下命令: grep -rl 'python' path

5 #即给出一个目录和patten,递归遍历查找该目录下含有该patten的文件完整路径,如果文件含有多行则需要去重;

6

7 importos8

9 definit(func): # 定义一个执行 next() 功能的装饰器;10 def wrapper(*args,**kwargs):11 res = func(*args,**kwargs)12 next(res)13 returnres14 returnwrapper15 @init16 defsearch_all_file(target):17 whileTrue:18 path = yield # 利用send()给yield传值,然后赋值给path

19 g =os.walk(path) # 根据给定path,遍历该目录下所有文件,也包含所有子目录下的文件;20 for path,_,files ing:21 for file infiles:22 target.send(r'%s\%s' %(path,file)) # 利用send()把遍历得到的所有文件传递给下一个生成器的yield;不接受yield的返回值;23 @init24 defopener(target):25 whileTrue:26 file_to_open = yield # 接收调用者传递的文件名,即 search_all_file()函数里send()的参数;

27 with open(file_to_open,encoding='utf-8') as rf:28 for line inrf: # 打开文件,遍历该文件内容;29 res =target.send((file_to_open,line)) # 利用send()把该文件名和每次遍历的每行内容传递给下一个生成器的yield;并用res接收返回值;30 ifres: # 需要注意的一点:send()参数只能是一个值,多个参数则可以以元组的形式传递;31 break

32 @init33 defgrep(patten):34 flag =False # 定义一个标识位35 whileTrue:36 the_file,line = yieldflag # 接收调用者传递的文件名和该文件名下遍历得到的每行内容;37 flag =False38 if patten inline:39 flag =True # 如果某个文件某行内容包含 patten 关键字,则将标识位置为 True,并再下一次调用的时候返回给调用者;40 print(the_file) # 打印匹配到的文件名;41

42 path = r'D:\soft\work\Python_17\day05\a' # path=r'path' --> r'xxx' 表示绝对 row data,表示不用转意;

43 g = search_all_file(opener(grep('python'))) # 注意这里的调用写法!!!44 print(g)45 g.send(path)

二、递归调用

1.递归的概念

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

包括两部分:递推和回溯;

1 deff1():2 print('from f1')3 f1()4

5 f1()

2.Python3中递归的层数限制

1 importsys2 print(sys.getrecursionlimit())    # 查看默认递归次数上限3 sys.setrecursionlimit(2000)      # 认为设置递归上限4 print(sys.getrecursionlimit())5

6 ---

7 1000

8 2000

3.递归特性

1. 必须有一个明确的结束条件;

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

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧;每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出);

4.堆栈扫盲:http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html

5.尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

4.递归具体应用

1.二分法查找某个元素

前提:输入的可循环对象必须是有序的;

1 num_list = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35,99]2

3 deffind_num(num_list, number):4 if 0 ==len(num_list):5 print('No exist.')6 return

7 mid_index = len(num_list)//2

8 mid_value =num_list[mid_index]9 if number >mid_value:10 num_list = num_list[mid_index+1:]11 find_num(num_list,number)12 elif number

699056-20170606225550262-62644005.png

ContractedBlock.gif

ExpandedBlockStart.gif

ContractedBlock.gif

ExpandedBlockStart.gif

ContractedBlock.gif

ExpandedBlockStart.gif

ContractedBlock.gif

ExpandedBlockStart.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值