二、装饰器

    所谓装饰器decorator仅仅是一种语法糖, 可作用的对象可以是函数也可以是类, 装饰器本身是一个函数, 其主要工作方式就是将被装饰的类或者函数当作参数传递给装饰器函数。本质上,装饰器就是一个返回函数的高阶函数
    假设有这么一个应用场景,一个公司的监控监控系统有很多函数用来监控不同的数据,突然有一天老大要把这么多函数,需要一个日志功能,也就是在执行函数前和执行函数后再控制台和文件中输出日志。
    如果老大把这个任务交个你,你会怎么做?把每个函数都修改一遍吗?如果老大觉得日志功能太影响性能,又要去掉,怎么办?一个又一个的改回来??如果函数少需要修改的地方少还可以,如果需要修改的地方很多的话,这样显然是不明智的。用装饰器就可以很好的解决这个问题。我们先来看一下装饰器如何定义。

1、定义装饰

 def log(func):
def wrapper(*args, **kwargs):
print('call %s():' % func.__name__)
return func(*args, **kwargs)
return wrapper
    说明:看上去和定义一个函数没多大区别,只不过在函数里有嵌套了一层函数而已。1)log为装饰器名称,可以随意定义,就像普通函数。2)装饰器的参数func为一个函数,表示要装饰的函数。3)装饰器里面的函数名可以随意,参数的话可以根据被装饰的函数的情况而定,参数的作用只是为了把参数有重新传回被装饰的函数。通常使用*args, **kwargs为了可以匹配各种函数的参数个数等
 

2、装饰器的调用

    调用装饰器来装饰函数,我们只需要使用Python的语法糖,在被装饰函数上方使用@装饰名的方式调用,比如我们要调用上面的log装饰器
 @log
def Foo():
print('Foo')
Foo()
执行结果
call Foo(): Foo

3、装饰器原理

    其实装饰器的调用@装饰器名是一个语法糖,Python解释器在解释到这里的时候为我们做了如下工作
 Foo = log(Foo)
    说明:
1)调用装饰器函数将被装饰的函数作为参数传递过去。
2)这样就相当于重构了这个函数,也就是包裹了一层内容。
3)装饰器本身一个可以接收参数,但是,由于使用场合比较少,甚少会用到,这里就不讲解了,其实原理就是在定义装饰器的时候在外面再裹上一层函数
 

三、递归

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
递归算法所体现的“重复”一般有三个要求:
(1) 每次调用在规模上都有所缩小(通常是减半);
(2) 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
(3) 在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。
 
实例,通过递归实现二分查找
 def binary_search(data_list,find_num):
mid_pos = int(len(data_list) /2 ) # 获取中间的索引
mid_val = data_list[mid_pos] # 获取中间的索引对相应元素,也就是值
print(data_list)
if len(data_list) >1: # 递归结束条件,也就是规模绩效
if mid_val > find_num: # 中间的值比要找的值大,说明在中间值左边
print("[%s] should be in left of [%s]" %(find_num,mid_val))
binary_search(data_list[:mid_pos],find_num) # 递归自己,继续查找自己的左边(也就是递归要求里的缩小调用规模)
elif mid_val < find_num: # 中间的值比要找的值大,说明在中间值左边
print("[%s] should be in right of [%s]" %(find_num,mid_val))
binary_search(data_list[mid_pos + 1:],find_num)
else: # 如果既不大于也不小于说明正好等于
print("Find ", find_num) else:
# 当列表的大小等于1的时候,不在调用自己,结束递归
if mid_val == find_num: # 判断最用一个元素是否等于要查找的数
print("Find ", find_num)
else:
print("cannot find [%s] in data_list" %find_num) if __name__ == '__main__':
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,104]
binary_search(primes,5)
binary_search(primes,66)
    执行结果
 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 104]
[5] should be in left of [47]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]
[5] should be in left of [19]
[2, 3, 5, 7, 11, 13, 17]
[5] should be in left of [7]
[2, 3, 5]
[5] should be in right of [3]
[5]
Find 5
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 104]
[66] should be in right of [47]
[53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 104]
[66] should be in left of [79]
[53, 59, 61, 67, 71, 73]
[66] should be in left of [67]
[53, 59, 61]
[66] should be in right of [59]
[61]
cannot find [66] in data_list
 

我的Python成长之路---第四天---Python基础(15)---2016年1月23日(寒风刺骨)的更多相关文章

  1. 我的Python成长之路---第四天---Python基础(16)---2016年1月23日(寒风刺骨)

    四.正则表达式     字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和 ...

  2. 我的Python成长之路---第四天---Python基础(14)---2016年1月23日(寒风刺骨)

    一.生成器和迭代器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. ...

  3. python成长之路——第四天

    内置函数: callable:查看对象是否能被调用(对象是函数的话能被调用) #callable def f1(): pass f2="a" print(callable(f1)) ...

  4. 我的Python成长之路---第七天---Python基础(21)---2016年2月27日(晴)

    四.面向对象进阶 1.类方法 普通的方法通过对象调用,至少有一个self参数(调用的时候系统自动传递,不需要手工传递),而类方法由类直接调用,至少有一个cls参数,执行时,自动将调用该方法的类赋值个c ...

  5. 我的Python成长之路---第三天---Python基础(12)---2016年1月16日(雾霾)

    四.函数 日常生活中,要完成一件复杂的功能,我们总是习惯把“大功能”分解为多个“小功能”以实现.在编程的世界里,“功能”可称呼为“函数”,因此“函数”其实就是一段实现了某种功能的代码,并且可以供其它代 ...

  6. 我的Python成长之路---第三天---Python基础(13)---2016年1月16日(雾霾)

    五.Python的常用的内置函数 Python为我们准备了大量的内置函数,如下图所示 这里我们只讨论红框内的内置函数 abs(x) 返回一个数的绝对值(模),参数可以是真说或浮点数 >>& ...

  7. 我的Python成长之路---第三天---Python基础(11)---2016年1月16日(雾霾)

    三.深浅拷贝 在Python中将一个变量的值传递给另外一个变量通常有三种:赋值.浅拷贝以及深拷贝 讨论深浅拷贝之前我们把Python的数据类型分为基本数据类型包括数字.字符串.布尔以及None等,还有 ...

  8. 我的Python成长之路---第三天---Python基础(10)---2016年1月16日(雾霾)

    二.collections collections是对Python现有的数据类型的补充,在使用collections中的对象要先导入import collections模块 1.Counter——计数 ...

  9. Python高手之路【四】python函数装饰器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

随机推荐

  1. .net format 中 大括号{}处理

    1.string string.format(string format,object arg0) 错误:因为方法中使用{n}做占位符号了,所以其他需要括号{}的地方,就需要{{}}

  2. windows如何安装scrapy

    第一次写博客,有不好的地方请理解! 在linux下安装scrapy几行命令就搞定了,windows就是事多! 话不多说,我们直接进入主题: 1. 下载python.地址 https://www.pyt ...

  3. selenium 学习笔记 ---新手学习记录(6) 问题总结(java)

    1.查看网页的cookie信息 //查看cookie 登录后的cookie Set<Cookie> setcoke= driver.manage().getCookies(); for(C ...

  4. 25_Downloading An Image

    一个App,从网上下载一张图片(给出图片地址),重新命名,然后保存到手机中,再从手机中取出显示在屏幕上. 难度不大,就是找图片很蛋疼,百度搜索出来的过一会儿会失效,Google搜索出来的有些需要FQ, ...

  5. 1_HelloWorld

    学iOS开发与学Swift是两件事情,Swift只是一种语言,它有官方手册,里面包含了全部的语法.对其他任何一门语言很熟悉的人,学习Swift可能只需要几天的时间.而这之后,学习iOS开发才是难点,有 ...

  6. ElasticSearch 插件配置

    http://blog.sina.com.cn/s/blog_8f31e5b10101dsnq.html http://www.tuicool.com/articles/mMZfu2 http://b ...

  7. [HDU 4666]Hyperspace[最远曼哈顿距离][STL]

    题意: 许多 k 维点, 求这些点之间的最远曼哈顿距离. 并且有 q 次操作, 插入一个点或者删除一个点. 每次操作之后均输出结果. 思路: 用"疑似绝对值"的思想, 维护每种状态 ...

  8. 【C++学习笔记】继承与派生基础概念

    面向对象的程序设计主要有四个特点:抽象.封装.继承和多态.其中继承是我认为最最重要的一个特性,可以说继承是面向对象的精华所在. 举一个继承的浅显易懂的例子:假如我们已经有了一个“马”的类,其中成员变量 ...

  9. js静态方法和实例方法

    js静态方法 function foo(){} // 声明类 foo.method = function(){} // 方法体 使用:foo.method() js实例方法 function foo( ...

  10. Linux新手笔记 ibus

    centos 6.4 32  笔记 一.安装gccyum install gcc    ======================================================== ...