python装饰器与递归算法详解


Posted in Python onFebruary 18, 2016

1、python装饰器

刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了。总结了一下解释得比较好的,通俗易懂的来说明一下:

小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣:

def sum1():
   sum = 1 + 2
   print(sum)
 sum1()

此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了:

import time
 
 def sum1():
   start = time.clock()
   sum = 1+2
   print(sum)
   end = time.clock()
   print("time used:",end - start)
 
 sum1()

运行之后,完美~~

可是随着继续翻看,小P对越来越多的函数感兴趣了,都想看下他们的运行时间如何,难道要一个一个的去改函数吗?当然不是!我们可以考虑重新定义一个函数timeit,将sum1的引用传递给他,然后在timeit中调用sum1并进行计时,这样,我们就达到了不改动sum1定义的目的,而且,不论小P看了多少个函数,我们都不用去修改函数定义了!

import time

def sum1():
  sum = 1+ 2
  print (sum)

def timeit(func):
  start = time.clock()
  func()
  end =time.clock()
  print("time used:", end - start)

timeit(sum1)

咂一看,没啥问题,可以运行!但是还是修改了一部分代码,把sum1() 改成了timeit(sum1)。这样的话,如果sum1在N处都被调用了,你就不得不去修改这N处的代码。所以,我们就需要杨sum1()具有和timeit(sum1)一样的效果,于是将timeit赋值给sum1。可是timeit是有参数的,所以需要找个方法去统一参数,将timeit(sum1)的返回值(计算运行时间的函数)赋值给sum1。

import time
 
 def sum1():
   sum = 1+ 2
   print (sum)
 
 def timeit(func):
   def test():
     start = time.clock()
     func()
     end =time.clock()
     print("time used:", end - start)
   return test
 
 sum1 = timeit(sum1)
 sum1()

这样一个简易的装饰器就做好了,我们只需要在定义sum1以后调用sum1之前,加上sum1= timeit(sum1),就可以达到计时的目的,这也就是装饰器的概念,看起来像是sum1被timeit装饰了!Python于是提供了一个语法糖来降低字符输入量。

import time
  
 def timeit(func):
   def test():
     start = time.clock()
     func()
     end =time.clock()
     print("time used:", end - start)
   return test
 
 @timeit
 def sum1():
   sum = 1+ 2
   print (sum)
 
 sum1()

重点关注第11行的@timeit,在定义上加上这一行与另外写sum1 = timeit(sum1)完全等价。

2、递归算法

递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法解决问题的特点:

(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

举个栗子:对一个数字进行除2求值,直到小于等于1时退出并输出结果

def divide(n,val):
  n += 1
  print(val)
  if val / 2 > 1:
    aa = divide(n,val/2)
    print('the num is %d,aa is %f' % (n,aa))
  print('the num is %d,val is %f' % (n,val))
  return(val)

divide(0,50.0)

结果说明(不return时相当于嵌套循环,一层层进入在一层层退出):

50.0
25.0
12.5
6.25
3.125
1.5625
the num is 6,val is 1.562500
the num is 5,aa is 1.562500
the num is 5,val is 3.125000
the num is 4,aa is 3.125000
the num is 4,val is 6.250000
the num is 3,aa is 6.250000
the num is 3,val is 12.500000
the num is 2,aa is 12.500000
the num is 2,val is 25.000000
the num is 1,aa is 25.000000
the num is 1,val is 50.000000

2、递归时return:

def divide(n,val):
  n += 1
  print(val)
  if val / 2 > 1:
    aa = divide(n,val/2)
    print('the num is %d,aa is %f' % (n,aa))
    return(aa)
  print('the num is %d,val is %f' % (n,val))
  return(val)

divide(0,50.0)

结果说明(return时就直接结束本次操作):

50.0
25.0
12.5
6.25
3.125
1.5625
the num is 6,val is 1.562500
the num is 5,aa is 1.562500
the num is 4,aa is 1.562500
the num is 3,aa is 1.562500
the num is 2,aa is 1.562500
the num is 1,aa is 1.562500

用递归实现斐波那契函数

def feibo(first,second,stop,list):

  if first >= stop or second >= stop:
    return list
  else:
    sum = first + second
    list.append(sum)
    if sum <= stop:
      return feibo(second,sum,stop,list)

  return list

if __name__ == '__main__':
  first = int(raw_input('please input the first number:'))
  second = int(raw_input('please input the second number:'))
  stop = int(raw_input('please input the stop number:'))
  l = [first,second]
  a = feibo(first,second,stop,l)
  print(a)
Python 相关文章推荐
paramiko模块安装和使用(远程登录服务器)
Jan 27 Python
将Python中的数据存储到系统本地的简单方法
Apr 11 Python
Flask框架中密码的加盐哈希加密和验证功能的用法详解
Jun 07 Python
python读取视频流提取视频帧的两种方法
Oct 22 Python
python机器学习之KNN分类算法
Aug 29 Python
django admin后台添加导出excel功能示例代码
May 15 Python
Python 异常处理Ⅳ过程图解
Oct 18 Python
Python 定义只读属性的实现方式
Mar 05 Python
python中not、and和or的优先级与详细用法介绍
Nov 03 Python
Python实现冒泡排序算法的完整实例
Nov 04 Python
python爬虫之selenium库的安装及使用教程
May 23 Python
python神经网络Xception模型
May 06 Python
Python利用Nagios增加微信报警通知的功能
Feb 18 #Python
Python多线程、异步+多进程爬虫实现代码
Feb 17 #Python
玩转python爬虫之爬取糗事百科段子
Feb 17 #Python
玩转python爬虫之正则表达式
Feb 17 #Python
玩转python爬虫之URLError异常处理
Feb 17 #Python
玩转python爬虫之cookie使用方法
Feb 17 #Python
Python 爬虫爬取指定博客的所有文章
Feb 17 #Python
You might like
php递归列出所有文件和目录的代码
2008/09/10 PHP
php eval函数用法 PHP中eval()函数小技巧
2012/10/31 PHP
php基于表单密码验证与HTTP验证用法实例
2015/01/06 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
2019/06/22 PHP
php设计模式之工厂方法模式分析【星际争霸游戏案例】
2020/01/23 PHP
jquery ajax 检测用户注册时用户名是否存在
2009/11/03 Javascript
js中字符替换函数String.replace()使用技巧
2011/08/14 Javascript
面向对象设计模式的核心法则
2013/11/10 Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
2015/03/04 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
5个最顶级jQuery图表类库插件【jquery插件库】
2016/05/05 Javascript
好好了解一下Cookie(强烈推荐)
2016/06/14 Javascript
Vue.js -- 过滤器使用总结
2017/02/18 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
layui使用数据表格实现购物车功能
2019/07/26 Javascript
深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)
2020/02/19 Javascript
vue+canvas实现移动端手写签名
2020/05/21 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
python连接池实现示例程序
2013/11/26 Python
Python自动登录126邮箱的方法
2015/07/10 Python
使用pandas 将DataFrame转化成dict
2019/12/10 Python
Python常用库Numpy进行矩阵运算详解
2020/07/21 Python
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
世界上最好的野生海鲜和有机食品:Vital Choice
2020/01/16 全球购物
伊莱克斯阿根廷网上商店:Tienda Electrolux
2021/03/08 全球购物
经济信息管理专业大学生求职信
2013/09/27 职场文书
市场营销专科应届生求职信
2013/11/24 职场文书
会计电算化学生个人的自我评价
2014/02/08 职场文书
宝宝满月酒主持词和仪式流程
2014/03/27 职场文书
校园运动会广播稿
2015/08/19 职场文书
nginx安装以及配置的详细过程记录
2021/09/15 Servers
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
2022/04/20 Python
mysql 获取相邻数据项
2022/05/11 MySQL