二、装饰器

    所谓装饰器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 基础错误-string.replace 方法

    1.string string.Replace(string oldValue,string newValue) 返回一个新的字符串,其中当前示例中出现的所有指定字符串都替换另一个指定字符串 错误:总 ...

  2. [LeetCode]题解(python):121-Best Time to Buy and Sell Stock

    题目来源: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 题意分析: 给定一个数组,代表array[i] 代表第i天的价 ...

  3. chroot命令

    CHROOT就是Change Root,也就是改变程序执行时所参考的根目录位置.通过chroot机制来更改某个进程所能看到的根目录,即将某进程限制在指定目录中,保证该进程只能对该目录及其子目录的文件有 ...

  4. Linux软件间的依赖关系(转)

    Linux中的软件大部分是零碎的,其粒度比windows的小很多,软件之间的依赖关系很强烈,下面是自己的一些理解: 一.Linux中的软件依赖Linux中的软件依赖关系成一颗拓扑树结构,比如A直接或间 ...

  5. EventStore的设计思路

    EventStore的设计思路 最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event ...

  6. C#使用WinAPI 修改电源设置,临时禁止笔记本合上盖子时睡眠

    原文 http://www.cnblogs.com/h46incon/archive/2013/09/03/3299138.html 在 阻止系统自动睡眠的小软件,附C#制作过程 ,弄了一个防止系统睡 ...

  7. JetBrains IntelliJ IDEA for Mac 15.0 破解版 – Mac 上强大的 Java 集成开发工具

    应网友要求更新. IntelliJ IDEA 是最强大的 Java IDE 之一,由知名的Jetbrainsg公司出品,最新版本增加了大量强大易用的特性,比如 Java 8 的Lambda 表达式调试 ...

  8. CodeIgniter中的session处理

    在CI中你可以这样很简单地装载library:     $this->load->library('newclass');    注意系统中会有两个library目录,一个是system/ ...

  9. perl5 第三章 操作符

    第三章 操作符 by flamephoenix 一.算术操作符二.整数比较操作符三.字符串比较操作符四.逻辑操作符五.位操作符六.赋值操作符七.自增自减操作符八.字符串联结和重复操作符九.逗号操作符十 ...

  10. HDU 3360 National Treasures

    题目大意:大厅每个位置都有一个文物或者一个守卫,文物是安全的前提是: 关键位置上必须有一个守卫,或者文物本身的位置上有一个守卫.求保证每个文物是安全的守卫的最少数量. #include <cst ...