1. 闭包函数
#闭包函数特点: 简而言之, 闭包的特点就是内部函数引用了外部函数中的变量。 在Python中,支持将函数当做对象使用,也就是可以将一个函数当做普通变量一样用作另一个函数的参数和返回值。
#闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,知道内部函数被调用结束。
闭包函数:示例
x = 10 # 全局变量
def get_number(x):
x=100 #局部变量
print(x)
print(x) #取全局变量值x=10
get_number(10) #无论实参填写多少,x都会在内部被赋值为100,x=100
x = 10 # 全局变量
def get_number():
def func():
x=100 #局部变量
print(x)
return func #把自己的函数名返回给了get_number函数
#get_number() =func get_number()() =func()
get_number= get_number() #装饰器的原型就是闭包函数的重新赋值,这样就做到了不改变调用方法给代码增加新功能的效果
get_number() #实际为func() x=100
2. 装饰器
因为前面已经在闭包函数中说明了装饰器的作用,这里就直接把装饰器示例展示一下吧
### 收银机代码
from functools import wraps
#收银机
def outer(sw): # switch 开关 带参数的装饰器
def count(func): # 外围函数,实参为需要被装饰器的函数
@wraps(func) # functools wraps模块,提供了内置函数的使用
def inner(dd): # 这里的参数为被装饰函数所需要的形参
if sw == 'on': #如果开关为on则执行
while True:
shopping = input('enter the price of goods,if enter 0 is over')
if shopping == '0':
break
else:
try: # try except (trycat 大概理解为捕捉错误,如果在函数编译期间遇到错误不报错不执行, 增加容错率)
list.append(float(shopping)) #把数字改变为float类型添加进列表
except:
print('error')
continue
elif sw == 'off':#如果开关为off则执行(不增加功能)
print('switch is off')
else:
print('prop error') # 装饰器函数填写错误
res = func(dd) #调用了被装饰函数本体
return res # 返回函数的返回值
return inner # 范围内函数(功能模块)
return count # 返回外围函数
list=[]
@outer('on')
def collection(list):
money = 0
for i in list:
money+=i
print('total consumption {:.2f}' .format(money))
3. 递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
递归函数特性:
1. 必须有一个明确的结束条件;
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
4. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
示例
# 取得get_age5的值
# 思路: get_age5 = get_age4+2
# get_age4 = get_age3+2
# get_age3 = get_age2+2
# get_age2 = get_age1+2
# get_age1 = 18
# 18+2=get_age2+2=get_age3+2=get_age4+2=get_age5
#18+2+2+2+2=26
def get_age(n):
if n == 1:
return 18 # 有明确的结束条件
return get_age(n-1) + 2
print(get_age(5))
#按照自己的思路写了下斐波那契数列
def age(x,y,z): # 这里没加xy都为1的判断,算个建议版本吧 z为最大值
print(x+y)
if x+y>z:
print('over')
return
else:
x,y=y,x+y
return age(x,y,z)
age(1,2,10000)
4. 手下二分法算法
特点: 数列必须为从小到大的有序数列,如果要寻找的数字在最边缘则可能效率更低
def dichotomy(l,target):
if len(l)==0:
return
middle_index = len(l)//2
if target > l[middle_index]:
l = l[middle_index:]
print(l)
dichotomy(l,target)
elif target < l[middle_index]:
l = l[:middle_index]
print(l)
dichotomy(l,target)
else:
print('找到了')