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 相关文章推荐
Python中无限元素列表的实现方法
Aug 18 Python
在Python中使用__slots__方法的详细教程
Apr 28 Python
Python实现扩展内置类型的方法分析
Oct 16 Python
Python内置模块hashlib、hmac与uuid用法分析
Feb 12 Python
Python连接Mssql基础教程之Python库pymssql
Sep 16 Python
Python找出微信上删除你好友的人脚本写法
Nov 01 Python
Python3.7 新特性之dataclass装饰器
May 27 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
Jun 08 Python
Python字典fromkeys()方法使用代码实例
Jul 20 Python
PyQt5的相对布局管理的实现
Aug 07 Python
详解python 支持向量机(SVM)算法
Sep 18 Python
Python使用cn2an实现中文数字与阿拉伯数字的相互转换
Mar 02 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学习笔记 (1) 环境配置与代码调试
2011/06/19 PHP
php中可能用来加密字符串的函数[base64_encode、urlencode、sha1]
2012/01/16 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
在laravel中使用Symfony的Crawler组件分析HTML
2017/06/19 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
2013/08/26 Javascript
JS实现页面超时后自动跳转到登陆页面
2015/01/19 Javascript
jQuery实现类似老虎机滚动抽奖效果
2015/08/06 Javascript
JavaScript编写简单的计算器
2015/11/25 Javascript
javascript类型系统_正则表达式RegExp类型详解
2016/06/24 Javascript
Bootstrap缩略图的创建方法
2017/03/22 Javascript
前端构建工具之gulp的配置与搭建详解
2017/06/12 Javascript
vue slots 组件的组合/分发实例
2018/09/06 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
[00:12]DAC SOLO赛卫冕冠军 VG.Paparazi灬展现SOLO技巧
2018/04/06 DOTA
[01:22:29]真视界:2019年国际邀请赛总决赛
2020/01/29 DOTA
简介Python中用于处理字符串的center()方法
2015/05/18 Python
通过Python 接口使用OpenCV的方法
2018/04/02 Python
python 实现A*算法的示例代码
2018/08/13 Python
Python之时间和日期使用小结
2019/02/14 Python
Django中自定义模型管理器(Manager)及方法
2019/09/23 Python
Timberland德国官网:靴子、鞋子、衣服、夹克及配件
2019/12/10 全球购物
美国在线面料商店:Fashion Fabrics Club
2020/01/31 全球购物
村委会主任先进事迹
2014/01/15 职场文书
双创工作实施方案
2014/03/26 职场文书
软件售后服务承诺书
2014/05/21 职场文书
优秀学生党员先进事迹材料
2014/05/29 职场文书
煤矿安全知识竞赛活动总结
2014/07/07 职场文书
我的梦想演讲稿500字
2014/08/21 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
政协常委会议主持词
2015/07/03 职场文书
2016年春节慰问信息大全
2015/11/30 职场文书
pycharm代码删除恢复的方法
2021/06/26 Python
HTML 里 img 元素的 src 和 srcset 属性的区别详解
2023/05/21 HTML / CSS