本节内容
1、装饰器
2、迭代器与生成器
3、内置方法
4、软件目录结构规范
一、装饰器
装饰器是一个用来装饰其他函数的工具,即为其他函数添加附加功能,其本质就是函数。
装饰器需要遵循的以下两个原则:
1、若要新增一个功能,就不能再修改源代码,即不能再修改被装饰函数的源代码。
2、不能修改被装饰函数的调用方式。
实现装饰器的知识储备:
1、函数即变量。
2、高阶函数。
3、函数嵌套。
即要想实现装饰器,首先应对以上三条知识有一定了解。
一、函数即变量
首先我们来简单介绍一下函数即变量这个概念。我们举一个简单的例子来说明:
def bar(): print('in the bar') def foo(): print('in the foo') bar() foo()
代码运行结果如下:
现在大家想象一下,如果把函数bar和函数foo的位置调换一下,还能运行吗?或者说运行结果还是一样吗?
我们试验一下:
def foo(): print('in the foo') bar() def bar(): print('in the bar') foo()
运行结果还是一样。
这说明在python中函数可看做是一个变量,定义一个函数与定义一个变量x并无二致,所以上述代码调换位置之后还是可以运行的。
二、高阶函数
在写一个装饰器函数时,我们也会用到高阶函数这个概念,它的主要思想就是把一个函数名当做实参传给另一个函数,以实现在不修改要装饰程序的源代码的情况下为其添加新功能的作用。下面我们举一个简单的例子进行说明。
def bar():
print('in the bar')
def test1(func):
print(func) #打印函数func的内存地址
func() #调用函数func
return (func) #返回函数func的内存地址
print(test1(bar)) #将函数bar作为实参传给func
上例通过函数test1来调用函数bar,我们可以看到代码运行结果如下:
上面是一个简单的高阶函数的例子,大家可以简单看一下结构,下面我们介绍一个具备简单功能的高阶函数的代码,如下:
import time def bar(): time.sleep(3) #bar函数实现延迟三秒输出的功能 print('in the bar') def test(func): start_time=time.time() func() end_time=time.time() print('the func run time is %s'%(end_time-start_time)) #为func函数添加一个计算函数执行时间的功能 return func #返回函数func的内存地址 bar=test(bar) bar()
代码执行结果如下:
我们可以看到通过高阶函数test,我们实现了为bar函数添加计算函数执行时间的功能,并且,通过把函数赋值给变量bar,我们实现了不改变原函数调用方式的前提下增加新功能的作用。
这既是装饰器的核心所在。
三、嵌套函数
在这一节我们介绍嵌套函数,函数的嵌套在装饰器中也发挥着非常重要的作用,示例如下:
def foo(): print('in the foo') def bar(): print('in the bar') bar() foo()
代码执行结果如下:
通过上述例子我们可以直观的看到局部作用域和全局作用域的访问顺序:先外后里。
四、装饰器
通过之前的热身,现在我们自己动手来写一个装饰器。
假设刚开始我们有两个函数test1和test2,我们想通过装饰器来添加一个计算函数运行时间的新功能,代码如下:
import time def timmer(func): def deco(*args,**kwargs): #这里用到参数组*args和**kwargs是针对可能出现func函数的形参个数不固定的情况而设定的 start_time=time.time() func(*args,**kwargs) end_time=time.time() print('the func run time is %s'%(end_time-start_time)) #计算函数func实际运行时间 return deco @timmer #test1=timmer(test1) def test1(): time.sleep(3) print('in the test1') @timmer #test2=timmer(test2) def test2(name): print('test2:',name) test1() #因之前@timmer操作,这里实际调用的是deco test2('abcd') #同理,这里调用的也是deco
这里,大家需要格外注意的是为了简洁,python中可以用@timmer来代替test1=timmer(test1),也就是上面高阶函数讲到的不改变函数调用方式。
代码运行结果如下:
我们可以看到装饰器圆满完成了“装饰”的功能。
学习完上述简单的装饰器程序,我们再挑战一下高难度的——我们用装饰器来写一个为某些网站设置登陆界面的代码,具体如下:
user,passwd='kobe','0824' #初始化用户名和密码 def auth(func): def wrapper(*args,**kwargs): username=input('username:').strip() password=input('password:').strip() if user==username and passwd==password: #验证用户名和密码是否正确 print('