本文摘自php中文网,作者零下一度,侵删。
装饰器()
1、装饰器:本质是函数;
装饰器(装饰其他函数),就是为其他函数添加附加功能;
原则:1.不能修改被装饰函数的源代码;
2.不能修改被装饰的函数的调用方式;
装饰器对被装饰的函数完全透明的,没有修改被装饰函数的代码和调用方式。
实现装饰器知识储备:
1.函数即“变量”;
2.高阶函数;
3.嵌套函数
高阶函数+嵌套函数=》装饰器
匿名函数(lambda表达式)
>>> calc = lambda x:x*3 >>> calc(2) 6
高阶函数:
a.把一个函数名当做实参传递给另外一个函数;
1
2
3
4
>>> def bar(): print(
"in the bar....."
)
>>> def foo(func):
print(func)>>> foo(bar)
<function bar at 0x7f8b3653cbf8>
b.返回值中包含函数名;
1
2
>>> import
time
>>> def foo():
time
.sleep(3) print(
"in the foo....."
)>>> def main(func): print(func)
return
func>>> t = main(foo)<function foo at 0x7fb7dc9e3378>>>> t()in the foo.....
在不修改源代码的情况下,统计程序运行的时间:
1
<span style=
"font-size: 16px"
>import time</span><br><br><span style=
"font-size: 16px"
>def timmer(func):</span><br><span style=
"font-size: 16px"
> def warpper(*args,**kwargs): #warpper(*args,**kwargs)万能参数,可以指定参数,也可以不指定参数</span><br><span style=
"font-size: 16px"
> start_time = time.time() #计算时间</span><br><span style=
"font-size: 16px"
> func()</span><br><span style=
"font-size: 16px"
> stop_time = time.time()</span><br><span style=
"font-size: 16px"
>
print
(
"the func run time is %s"
%(stop_time-start_time)) #计算函数的运行时间</span><br><span style=
"font-size: 16px"
>
return
warpper</span><br><br><span style=
"font-size: 16px"
>@timmer #等价于test1 = timmer(test1),因此函数的执行调用是在装饰器里面执行调用的</span><br><span style=
"font-size: 16px"
>def test1():</span><br><span style=
"font-size: 16px"
> time.sleep(3)</span><br><span style=
"font-size: 16px"
>
print
(
"in the test1"
)</span><br><br><span style=
"font-size: 16px"
>test1()<br>运行结果如下:<br></span>
in the test1 the func run time is 3.001983404159546
装饰器带参数的情况:
1
<span style=
"font-size: 16px; font-family: 宋体"
>import time</span><br><br><span style=
"font-size: 16px; font-family: 宋体"
>def timmer(func):</span><br><span style=
"font-size: 16px; font-family: 宋体"
> def warpper(*args,**kwargs):</span><br><span style=
"font-size: 16px; font-family: 宋体"
> start_time = time.time() #计算时间</span><br><span style=
"font-size: 16px; font-family: 宋体"
> func(*args,**kwargs) #执行函数,装饰器参数情况</span><br><span style=
"font-size: 16px; font-family: 宋体"
> stop_time = time.time()</span><br><span style=
"font-size: 16px; font-family: 宋体"
>
print
(
"the func run time is %s"
%(stop_time-start_time)) #计算函数的运行时间</span><br><span style=
"font-size: 16px; font-family: 宋体"
>
return
warpper #返回内层函数名</span><br><br><span style=
"font-size: 16px; font-family: 宋体"
>@timmer</span><br><span style=
"font-size: 16px; font-family: 宋体"
>def test1():</span><br><span style=
"font-size: 16px; font-family: 宋体"
> time.sleep(3)</span><br><span style=
"font-size: 16px; font-family: 宋体"
>
print
(
"in the test1"
)</span><br><br><span style=
"font-size: 16px; font-family: 宋体"
>@timmer #test2 = timmer(test2)</span><br><span style=
"font-size: 16px; font-family: 宋体"
>def test2(name):</span><br><span style=
"font-size: 16px; font-family: 宋体"
>
print
(
"in the test2 %s"
%name)</span><br><br><span style=
"font-size: 16px; font-family: 宋体"
>test1()</span><br><span style=
"font-size: 16px; font-family: 宋体"
>test2(
"alex"
)<br>运行结果如下:<br></span>
in the test1 the func run time is 3.0032410621643066 in the test2 alex the func run time is 2.3603439331054688e-05
装饰器返回值情况:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import time
user,passwd =
"alex"
,
"abc123"
def auth(func):
def wrapper(*args,**kwargs):
username = input(
"Username:"
).strip()
password = input(
"Password:"
).strip()
if
user == username
and
passwd == password:
print
(
"\033[32;1mUser has passed authentication.\033[0m"
)
return
func(*args,**kwargs) #实际上执行调用的函数
# res = func(*args,**kwargs)
#
return
res #函数返回值的情况,因为装饰器调用的时候是在装饰器调用的函数,因此返回值也在这个函数中
else
:
exit
(
"\033[31;1mInvalid username or password.\033[0m"
)
return
wrapper
def index():
print
(
"welcome to index page..."
)
@auth
def home():
#用户自己页面
print
(
"welcome to home page..."
)
return
"form home..."
@auth
def bbs():
print
(
"welcome to bbs page"
)
index()
print
(home())
bbs()
装饰器带参数的情况:
实现:1、本地验证;2、远程验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import time
user,passwd =
"alex"
,
"abc123"
def auth(auth_type):
''
'函数的多层嵌套,先执行外层函数'
''
print
(
"auth_type"
,auth_type)
def out_wrapper(func):
def wrapper(*args,**kwargs):
print
(
"wrapper func args:"
,*args,**kwargs)
if
auth_type ==
"local"
:
username = input(
"Username:"
).strip()
password = input(
"Password:"
).strip()
if
user == username
and
passwd == password:
print
(
"\033[32;1mUser has passed authentication.\033[0m"
)
func(*args,**kwargs) #实际上执行调用的函数
# res = func(*args,**kwargs)
#
return
res #函数返回值的情况,因为装饰器调用的时候是在装饰器调用的函数,因此返回值也在这个函数中
else
:
exit
(
"\033[31;1mInvalid username or password.\033[0m"
)
elif auth_type ==
"ldap"
:
print
(
"搞毛线lbap,傻逼...."
)
return
wrapperreturn out_wrapper
def index():
print
(
"welcome to index page..."
)
@auth(auth_type=
"local"
)
def home():
#用户自己页面
print
(
"welcome to home page..."
)
return
"form home..."
@auth(auth_type=
"ldap"
)
def bbs():
print
(
"welcome to bbs page"
)
index()
home()
bbs() #函数没有,因为没有调用函数,函数的调用在装饰器里面,是装饰器调用了函数
迭代器和生成器
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
>>> l1 = (i for i in range(10)) >>> l1 <generator object <genexpr> at 0x7f6a9fbcaeb8> >>> l1.__next__() 0 >>> l1.__next__() 1 生成器:只有在调用时才会生成相应的数据;
只有通过__next__()方法进行执行,这种能够记录程序运行的状态,yield用来生成迭代器函数。(只能往后调用,不能向前或者往后推移,只记住当前状态,因此银行的系统用来记录的时候可以使用yield函数)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
%= %= consumer(= consumer( i range(,)
运行如下:
A准备吃包子了......
B准备吃包子了......
包子1被A吃了......
包子1被B吃了......
包子2被A吃了......
包子2被B吃了......
包子3被A吃了......
包子3被B吃了......
包子4被A吃了......
包子4被B吃了......
包子5被A吃了......
包子5被B吃了......
包子6被A吃了......
包子6被B吃了......
包子7被A吃了......
包子7被B吃了......
包子8被A吃了......
包子8被B吃了......
包子9被A吃了......
包子9被B吃了.....
迭代器
我们已经知道,可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
可以使用isinstance()
判断一个对象是否是Iterable
对象
1
2
3
4
5
6
7
8
9
10
11
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance(
'abc'
, Iterable)
True
>>> isinstance((x
for
x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
以上就是python中的装饰器、生成器与迭代器介绍的详细内容,更多文章请关注木庄网络博客 !!
相关阅读 >>
操作Python 实现npy格式文件转换为txt文件
使用Python 操作excel文件
解析Python 代码注释规范代码
Python 和julia学哪个
Python 中set不常用吗
Python 中文件操作的相关内容总结(附示例)
turtle.done()的作用是什么
Python 多线程共享全局变量的实现代码
string在Python 中是什么意思
Python 中可变对象和不可变对象的讲解
更多相关阅读请进入《Python 》频道 >>
¥69.8元 人民邮电出版社
python入门书籍,非常畅销,超高好评,python官方公认好书。
转载请注明出处:木庄网络博客 » python中的装饰器、生成器与迭代器介绍