函数的产生可以使代码可以重复使用。
递归的产生可以 使函数重复使用自己,但是python默认递归的深度为1000,这个深度是可以修改的。
自己理解:递归虽然可以重复使用但是,需要设置一个条件,这个条件就是使递归跳出循环的。
def age(n): if n == 1: return 40 return age(n-1)+2
递归进行二分查找:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
def find(lst,aim): #这种算法可以在查找的值存在的情况下,不会报错,但是在,查找不 存在的值时,就会报错。 mid = len(lst)//2 if aim > lst[mid]: find(lst[mid+1:],aim) elif aim < lst[mid]: find(lst[:mid],aim) else:print(aim,mid)find(ls,66) #现在的方法可以解决,查找如果不存在的值不报错def find(lst,aim): mid = len(lst)//2 if mid: if aim > lst[mid]: find(lst[mid+1:],aim) elif aim < lst[mid]: find(lst[:mid],aim) else:print(aim,mid) else:print("你查找的值不存在")find(ls,66)
如何在二分查找的时候知道索引值
函数参数,如果在不确定用户是否传值的情况下,可以使用默认参数,None
递归时,列表,所以要先判断 开始值小于结束值
递归进阶:
需要在原装饰器的基础上增加一个函数,为了把函数传进去。目的是为了装饰器内部使用一定的外部条件,带参数的装饰器。
两种方式:返回装饰器内部的值:第一种:全局变量,第二种:写入到文件里 第三种:写入到数据库
同一个函数被两个装饰器装饰:先执行第一个装饰器的第一个语句,然后执行第二个装饰器的全部。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
def wrapper1(func): def inner1(*args,**kwargs): print('in wrapper 1,before') ret = func(*args,**kwargs) #qqxing print('in wrapper 1,after') return ret return inner1def wrapper2(func): #inner1 def inner2(*args,**kwargs): print('in wrapper 2,before') ret = func(*args,**kwargs) #inner1 print('in wrapper 2,after') return ret return inner2@wrapper2 #wrapper2 = wrapper2(inner1)@wrapper1def qqxing(): #qqxing = @wrapper1(qqxing) print('qqxing')qqxing() #inner2
递归的特性
递归的最大深度——997
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
def foo(n): print(n) n += 1 foo(n)foo(1)
由此我们可以看出,未报错之前能看到的最大数字就是997.当然了,997是python为了我们程序的内存优化所设定的一个默认值,我们当然还可以通过一些手段去修改它:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
import sysprint(sys.setrecursionlimit(100000))
三级菜单使用递归实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {},}menu
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
l = [menu]while l: for key in l[-1]:print(key) k = input('input>>').strip() # 北京 if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k]) elif k == 'b':l.pop() elif k == 'q':break
递归函数与二分查找算法
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 如果这样,假如我要找的数比列表中间的数还大,是不是我直接在列表的后半边找就行了?
简单版二分法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]def func(l,aim): mid = (len(l)-1)//2 if l: if aim > l[mid]: func(l[mid+1:],aim) elif aim < l[mid]: func(l[:mid],aim) elif aim == l[mid]: print("bingo",mid) else: print('找不到')func(l,66)func(l,6)
升级版二分法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
def search(num,l,start=None,end=None): start = start if start else 0 end = end if end else len(l) - 1 mid = (end - start)//2 + start if start > end: return None elif l[mid] > num : return search(num,l,start,mid-1) elif l[mid] < num: return search(num,l,mid+1,end) elif l[mid] == num: return mid
反射
什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
反射原理
通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(一切皆对象,类本身也是一个对象
hasattr、getattr、setattr、delattr
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
class Foo: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name)obj=Foo('egon',73)#检测是否含有某属性print(hasattr(obj,'name'))print(hasattr(obj,'say_hi'))#获取属性n=getattr(obj,'name')print(n)func=getattr(obj,'say_hi')func()print(getattr(obj,'aaaaaaaa','不存在啊')) #报错#设置属性setattr(obj,'sb',True)setattr(obj,'show_name',lambda self:self.name+'sb')print(obj.__dict__)print(obj.show_name(obj))#删除属性delattr(obj,'age')delattr(obj,'show_name')delattr(obj,'show_name111')#不存在,则报错print(obj.__dict__)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print getattr(Foo, 'staticField')print getattr(Foo, 'func')print getattr(Foo, 'bar')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#!/usr/bin/env python# -*- coding:utf-8 -*-import sysdef s1(): print 's1'def s2(): print 's2'this_module = sys.modules[__name__]hasattr(this_module, 's1')getattr(this_module, 's2')
导入其他模块,利用反射查找该模块是否存在某个方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#!/usr/bin/env python# -*- coding:utf-8 -*-def test(): print('from the test')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#!/usr/bin/env python# -*- coding:utf-8 -*- """程序目录: module_test.py index.py 当前文件: index.py"""import module_test as obj#obj.test()print(hasattr(obj,'test'))getattr(obj,'test')()