递归函数与模块
一、内置函数2(map、reduce、filter)
1、map
map(函数地址, 可迭代对象) ---> map对象
map会将可迭代对象中的每一个值进行修改,然后映射一个map对象中,
可以再将map对象转换成列表/元组。
注意: 只能转一次
1 # map 2 name_list = ['a','b','c','d','e','f'] 3 map_obj = map(lambda name: name + '_str' if name == 'b' else name + '_STR', name_list) 4 print(map_obj) 5 # map_obj ---> list/tuple 6 print(list(map_obj)) # map_obj ---> 生成器(迭代器) ---> 用完后,不能再取了 7 print(tuple(map_obj))
2、reduce
reduce: 合并
reduce(函数地址, 可迭代对象, 默认为0)
reduce(函数地址, 可迭代对象, 初始值)
1 # reduce 2 from functools import reduce 3 # 每次从可迭代对象中获取两个值进行合并, 4 # 初始值: 执行reduce函数时,都是从初始值开始合并 5 reduce(lambda x, y: x + y, range(1, 101), 0) 6 7 # 需求: 求1——100的和 8 # 普通 9 count = 0 10 for i in range(1,101): 11 count += i 12 print(count) 13 # 5050 14 15 # reduce版 16 from functools import reduce 17 count = reduce(lambda x, y: x + y, range(1, 101), 1000) 18 print(count) 19 6050
3、filter
filter: 过滤
filter(函数地址, 可迭代对象) --> filter 对象
1 # filter 2 name_list = ['a_str', 'b_str', 'c_str', 'd'] 3 filter_obj = filter(lambda x: x, name_list) 4 print(filter_obj) 5 6 # 将后缀为_str的名字 “过滤出来” 7 # filter会将函数中返回的结果为True 对应 的参数值 “过滤出来” 8 # 过滤出来的值会添加到 filter对象中 9 filter_obj = filter(lambda name: name.endswith('_str'), name_list) 10 print(filter_obj) 11 print(list(filter_obj))
二、递归
函数递归:
函数递归指的是重复 “直接调用或间接调用” 函数本身,
这是一种函数嵌套调用的表现形式。
直接调用: 指的是在函数内置,直接调用函数本身。
1 def func(): 2 print('from func') 3 func() 4 func()
间接调用: 两个函数之间相互调用间接造成递归。
1 # 间接递归 2 count = 0 3 def foo(): 4 global count 5 count += 1 6 print('from foo', count) 7 goo() 8 9 def goo(): 10 global count 11 count += 1 12 print('from goo', count) 13 foo() 14 15 # foo() 16 def func(): 17 try: 18 foo() 19 except RecursionError: 20 return 21 func()
python中有递归默认深度: 限制递归次数:998, 1000
PS: 但是在每一台操作系统中都会根据硬盘来设置默认递归深度。
获取递归深度:
sys.getrecursionlimit()
设置递归深度:
sys.setrecursionlimit(深度值)
单纯的递归调用时没有任何意义的
想要递归有意义,必须遵循两个条件:
- 回溯:
指的是重复地执行, 每一次执行都要拿到一个更接近于结果的结果,
回溯必要有一个终止条件。
- 递推:
当回溯找到一个终止条件后,开始一步一步往上递推。
1 # age5 == age4 + 2 2 # age4 == age3 + 2 3 # age3 == age2 + 2 4 # age2 == age1 + 2 5 # age1 == 18 # 回溯终止的结果 6 # result = age(n - 1) + 2 7 8 def age(n): 9 if n == 1: 10 return 18 11 # 这里写return才能实现递推 12 return age(n - 1) + 2 13 print(age(5)) # 26
三、模块
1、什么是模块?
模块是一系列功能的结合体
相当于与模块包着一堆函数与代码。
模块本质上是一个个的.py文件。
2、模块的三种来源:
1.python内置的模块: (python解释器的)
比如: sys\time\os\turtle
2.第三方的模块: (别人写的)
比如: requests
3.自定义的模块: (自己写的)
比如: 自己定义的demo.py文件
3、模块的四种表现形式:
1.使用python编写的py文件。(了解)
2.编译后的共享库DLL或者是C或者C++库。(了解)
3.包下面带有__init__.py的一组py文件。
- py_demo
- __init__.py
- demo.py
- demo2.py
4.python解释器下的py文件。
- python解释器下的文件夹
- 一个个的py文件
4、为什么要使用模块?
模块可以帮我们更好地管理功能代码,比如: 函数...
可以将项目拆分成一个个的功能,分别存放在不同的py文件(模块)中。
5、如何创建,编写模块,并使用模块?
- 创建py文件
- 在py文件编写python代码
- 在一个文件中,通过import关键字导入模块
import 模块名
# 注意: import 模块时,模块不能加.py后缀
在使用模块阶段,必须要注意,谁是执行文件,谁是被导入文件(被导入的模块)
- 模块在首次导入时,就已经固定好了,当前文件查找的顺序是先从内存中查找
- 模块在导入时发生的事情:
1.会先执行当前执行文件,并产生执行文件中的名称空间。
2.当执行到导入模块的代码时,被导入的模块会产生一个模块的名称空间。
3.会将被导入模块的名称空间加载到内存中。
- 给模块起别名 as
import 模块 as 模块的别名
- 模块的导入方式
- import 模块
- 在执行文件中直接import导入
- from 包/模块 import 模块/(函数名、变量名、类名)
- 在执行文件中直接import导入
6、循环导入问题
建立两个模块
model1.py
1 from model2 import name 2 name = 'jason'
model2.py
1 from model1 import name 2 name = 'tank'
执行文件run.py
import model2
程序会一直循环,直到触发最大循环机制而报错退出
- 解决循环导入问题:
1.需要查找的名字放在导入模块的上方
2.在函数内部导入,将模块变成函数名称空间中的名字
四、软件开发目录规范
注意: 每一次写项目时,都要新建一个文件夹与项目工程,必须让项目文件夹作为项目根目录。
- 项目的文件夹
- conf:
- 用于存放配置文件的文件夹
- core:
- 核心业务代码 .py
- interface:
- 接口, 接口内写获取数据前的逻辑代码,通过后才能获取数据
- db:
- 用于存放文件数据
- lib:
- 存放公共功能文件
- log:
- 用于存放日志文件,日志用于记录用户的操作记录
- bin:
- 里面存放启动文件 / - 启动文件
- readme.txt:
- 项目说明书, 用户告诉使用者项目的操作