python装饰器与递归算法详解
1、python装饰器
刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了。总结了一下解释得比较好的,通俗易懂的来说明一下:
小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣:
defsum1(): sum=1+2 print(sum) sum1()
此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了:
importtime defsum1(): start=time.clock() sum=1+2 print(sum) end=time.clock() print("timeused:",end-start) sum1()
运行之后,完美~~
可是随着继续翻看,小P对越来越多的函数感兴趣了,都想看下他们的运行时间如何,难道要一个一个的去改函数吗?当然不是!我们可以考虑重新定义一个函数timeit,将sum1的引用传递给他,然后在timeit中调用sum1并进行计时,这样,我们就达到了不改动sum1定义的目的,而且,不论小P看了多少个函数,我们都不用去修改函数定义了!
importtime defsum1(): sum=1+2 print(sum) deftimeit(func): start=time.clock() func() end=time.clock() print("timeused:",end-start) timeit(sum1)
咂一看,没啥问题,可以运行!但是还是修改了一部分代码,把sum1()改成了timeit(sum1)。这样的话,如果sum1在N处都被调用了,你就不得不去修改这N处的代码。所以,我们就需要杨sum1()具有和timeit(sum1)一样的效果,于是将timeit赋值给sum1。可是timeit是有参数的,所以需要找个方法去统一参数,将timeit(sum1)的返回值(计算运行时间的函数)赋值给sum1。
importtime defsum1(): sum=1+2 print(sum) deftimeit(func): deftest(): start=time.clock() func() end=time.clock() print("timeused:",end-start) returntest sum1=timeit(sum1) sum1()
这样一个简易的装饰器就做好了,我们只需要在定义sum1以后调用sum1之前,加上sum1=timeit(sum1),就可以达到计时的目的,这也就是装饰器的概念,看起来像是sum1被timeit装饰了!Python于是提供了一个语法糖来降低字符输入量。
importtime deftimeit(func): deftest(): start=time.clock() func() end=time.clock() print("timeused:",end-start) returntest @timeit defsum1(): sum=1+2 print(sum) sum1()
重点关注第11行的@timeit,在定义上加上这一行与另外写sum1=timeit(sum1)完全等价。
2、递归算法
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1)递归就是在过程或函数里调用自身。
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4)在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
举个栗子:对一个数字进行除2求值,直到小于等于1时退出并输出结果
defdivide(n,val): n+=1 print(val) ifval/2>1: aa=divide(n,val/2) print('thenumis%d,aais%f'%(n,aa)) print('thenumis%d,valis%f'%(n,val)) return(val) divide(0,50.0)
结果说明(不return时相当于嵌套循环,一层层进入在一层层退出):
50.0 25.0 12.5 6.25 3.125 1.5625 thenumis6,valis1.562500 thenumis5,aais1.562500 thenumis5,valis3.125000 thenumis4,aais3.125000 thenumis4,valis6.250000 thenumis3,aais6.250000 thenumis3,valis12.500000 thenumis2,aais12.500000 thenumis2,valis25.000000 thenumis1,aais25.000000 thenumis1,valis50.000000
2、递归时return:
defdivide(n,val): n+=1 print(val) ifval/2>1: aa=divide(n,val/2) print('thenumis%d,aais%f'%(n,aa)) return(aa) print('thenumis%d,valis%f'%(n,val)) return(val) divide(0,50.0)
结果说明(return时就直接结束本次操作):
50.0 25.0 12.5 6.25 3.125 1.5625 thenumis6,valis1.562500 thenumis5,aais1.562500 thenumis4,aais1.562500 thenumis3,aais1.562500 thenumis2,aais1.562500 thenumis1,aais1.562500
用递归实现斐波那契函数
deffeibo(first,second,stop,list): iffirst>=stoporsecond>=stop: returnlist else: sum=first+second list.append(sum) ifsum<=stop: returnfeibo(second,sum,stop,list) returnlist if__name__=='__main__': first=int(raw_input('pleaseinputthefirstnumber:')) second=int(raw_input('pleaseinputthesecondnumber:')) stop=int(raw_input('pleaseinputthestopnumber:')) l=[first,second] a=feibo(first,second,stop,l) print(a)