## 一、函数的递归调用
### 1、引入
```python
# 函数递归调用就是在调用一个函数的过程中直接或者间接地调用了自己
# 直接调用自己
def foo():
print('hello')
foo()
# 间接的调用
def bar():
foo()
def foo():
bar()
foo()
# 由于递归会无限的申请名称空间,导致内存溢出,所以python设置了最大的递归层数
import sys
print(sys.getrecursionlimit()) # 获取最大层数
print(sys.setrecursionlimit(2000)) # 设置最大层数
# 由此可知,需要在某种条件下结束递归
2、递归的两个阶段
回溯:一层一层的调用下去
递推:在满足某种条件下结束回溯,原路返回
# salary(5) = salary(4) + 10
# salary(4) = salary(3) + 10
# salary(3) = salary(2) + 10
# salary(2) = salary(1) + 10
# salary(1) = 18
# n=1 salary(n) = 18
# n!=1 salary(n) = salary(n-1) + 10
def salary(n):
if n == 1:
return 18
return salary(n-1) + 10
res = salary(5)
print(res)
=====>58
# nums=[111,[222,[333,[444,[5555,[6666,[777,[888,[9999]]]]]]]]]
#
#
# def func(l):
# for x in l:
# if type(x) is list:
# # 把自身的代码重新再调用一次
# func(x)
# else:
# print(x)
# func(nums)
算法之二分法
nums = [1,2,3,4,5,6,7,8,9,10]
def binary(l, n):
reserch_num = len(l) // 2
if len(l) == 0:
print('not in')
return
if n > reserch_num:
new_l = l[reserch_num + 1:]
return binary(new_l, n)
elif n < reserch_num:
new_l = l[: reserch_num]
return binary(new_l, n)
else:
print('find it')
二、三元表达式
def max2(x, y):
if x > y:
return x
else:
return y
三元表达式:表达式1 if 条件 else 表达式2
x = 111
y = 222
res = x if x >y else y
print(res)
=====>222
三、匿名函数
res = (lambad x, y: x + y)(1, 2)
print(res)
=====>3
特点:没有名字意味着调用一次后,变会被回收。
salaries = {
'egon': 4.4,
"lqz": 3.3,
'yj': 2.2
}
# def func(k):
# return salaries[k]
#
# print(max(salaries, key=lambda k:salaries[k]))
# print(min(salaries, key=lambda k:salaries[k]))
# print(sorted(salaries,key=lambda k:salaries[k],reverse=True))
map()函数的格式是:
map(function,iterable,...)
四、模块
1、什么是模块
模块就是一个功能的集合体,不是用来直接运行,而是用来被导入使用的
模块分为三大来源:
1、内置的模块
2、第三方模块
3、自定义的模块
模块分为四种类别:
1、一个py文件就是一个模块
2、一个文件夹也是一个模块=》包
3、已被编译为共享库或DLL的C或C++扩展
4 使用C编写并链接到python解释器的内置模块
2、为何要用模块
使用别人的模块:
1、拿来主义,提升开发效率
自定义模块:
1、别人的功能不够用了,需要自己的去编写
2、解决代码冗余
3、如何用模块
# 文件名是spam.py,模块名则是spam
x=111
import spam
# 首次导入模块发生的事情
# 1、触发被导入的模块的运行,产生一个模块的名称空间,把模块中的名字都丢进去
# 2、会在当前执行文件中得到一个全局名称空间的名字spam,该名字是指向被导入模块的名称空间的
# 之后的导入,名字spam直接引用首次导入产生的名称空间,不会再执行模块的内的代码了
# import spam
# import spam
# import spam
money = 2000
# print(money)
# print(spam.money)
# spam.read1()
# def read1():
# print('run1.py----read1')
# spam.read2()
# spam.change()
# print(spam.money)
# print(money)
# 一行导入多个模块
import spam,m1,m2,m3 # 不推荐
# 为导入的模块起别名
mysql.py
def sqlparse():
print('from mysql sqlparse')
oracle.py
def sqlparse():
print('from oracle sqlparse')
test.py
db_type = input('请输入数据类型:')
if db_type == 'mysql':
import mysql as db
elif db_type == 'oracle':
import oracle as db
db.sqlparse()
# 文件名是spam.py,模块名则是spam
x=111
# from spam import money,read1,read2 # money=spam.money,read1=spam.read1,read2=spam.read2
# 首次导入模块发生的事情
# 1、触发被导入的模块的运行,产生一个模块的名称空间,把模块中的名字都丢进去
# 2、会在当前执行文件中得到名字
# money=模块spam中的money对应值的内存地址
# read1=模块spam中的read1对应值的内存地址
# read2=模块spam中的read2对应值的内存地址
# from spam import money,read1,read2
# from spam import money,read1,read2
# from spam import money,read1,read2
# from spam import money,read1,read2
# print(money)
# print(read1)
# print(read2)
# money=111
# print(money)
# money=2000
# read1()
# def read1():
# print('run.py read1')
# read2()
# 一行导入多个名字
# from spam import money,read1
# 为导入的模块起别名
# from spam import money as m
#
# print(m)
# from spam import *
from spam import *
# print(money)
# print(read1)
# print(read2)
print(change)
在模块里使用`__all__`[函数名1,函数名2],在执行文件里,*只能导入[]内的函数
模块的命名用的是纯小写加划线
也可以在函数内导入模块,区别在于函数内的模块所在的是函数的局部名称空间
所有py文件内部都有__name__
的功能,当做执行文件时,print的结果是__main__
,当做模块被导入时,print的结果是模块的名字