函数的产生可以使代码可以重复使用。
递归的产生可以 使函数重复使用自己,但是python默认递归的深度为1000,这个深度是可以修改的。
自己理解:递归虽然可以重复使用但是,需要设置一个条件,这个条件就是使递归跳出循环的。
def age(n): if n == 1: return 40 return age(n-1)+2
递归进行二分查找:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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 inner1 def 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) @wrapper1 def qqxing(): #qqxing = @wrapper1(qqxing) print('qqxing') qqxing() #inner2
递归的特性
递归的最大深度——997
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
def foo(n): print(n) n += 1 foo(n) foo(1)
由此我们可以看出,未报错之前能看到的最大数字就是997.当然了,997是python为了我们程序的内存优化所设定的一个默认值,我们当然还可以通过一些手段去修改它:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import sys print(sys.setrecursionlimit(100000))
三级菜单使用递归实现
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, } menu
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#!/usr/bin/env python # -*- coding:utf-8 -*- import sys def s1(): print 's1' def s2(): print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')
导入其他模块,利用反射查找该模块是否存在某个方法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#!/usr/bin/env python # -*- coding:utf-8 -*- def test(): print('from the test')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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')()