python3自动化学习04

概要:迭代器、yield生成器、装饰器、递归函数、简单的算法(二分查找,二维数组)、正则表达式基础

一、迭代器

迭代器是访问集合元素的一种方式,迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。

迭代器只能往前不能后退。迭代器的一大优点就是不要求事先准备好整个迭代的过程中所有的元素,迭代器仅仅是在迭代到某个元素才计算该元素,而在这之前或之后,元素可以不存在或者销毁,这个特点使它特别适用于遍历一些巨大或无限的集合。

特点:

  1.访问者不需要关心迭代器内部的结构,仅仅需要通过 __next__() 方法不断去获取下一个内容

  2.不能随机访问集合中的某个值,只能从头到尾依次访问

  3.访问到一半时不能回退

  4.便于循环大的数据集合,节省内存

生成一个迭代器

1 #!/usr/bin/env python3
2 #author:Alnk
3 
4 names = iter(['a','b','c','d'])
5 print(names)
6 print(names.__next__())
7 print(names.__next__())
8 print(names.__next__())
9 print(names.__next__())
View Code

附加:

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 f = open("t.txt","r")
 4 
 5 #f.read()  #把文件内容全部读取到内存中,文件越大花费时间越长,是字符串形式
 6 s1 = f.read()
 7 print(s1)
 8 print(type(s1))
 9 
10 #f.readline()  #每次只读取一行,是字符串形式
11 s1 = f.readline()
12 print(s1)
13 print(type(s1))
14 s2 = f.readline()
15 print(s2)
16 print(type(s2))
17 
18 #f.readlines() #把所有行读取,然后变成一个列表的形式,文件越大花费时间越长
19 s1 = f.readlines()
20 print(s1)
21 print(type(s1))
22 
23 #通过迭代的形式去读取这个文件,是字符串
24 for i in f:
25     print(i)
26 print(type(i))'''
read、readline、readlines

二、生成器 yield

一个函数调用时返回一个迭代器,那这个函数就叫生成器。如果函数中包含 yield 语法,那这个函数就会变成生成器。

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 
 4 def cash_out(amount):
 5     while amount > 0:
 6         amount -=100
 7         yield 100
 8         print("又来取钱")
 9 
10 atm = cash_out(500)
11 print(type(atm))
12 print(atm.__next__())
View Code 

yield作用:可以使函数中断,并保存中断状态。中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

另外,yield还可以在单线程的情况下实现并发的运算效果

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 import time
 4 
 5 def consumer(name):
 6     print("%s 准备吃包子啦" %(name))
 7     while True:
 8         baozi = yield
 9         print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
10 
11 def producer():
12     c = consumer("张三")
13     c2 = consumer("李四")
14     c.__next__()
15     c2.__next__()
16     print("劳资开始做包子啦!")
17     for i in range(5):
18         time.sleep(1)
19         print("做了2个包子")
20         c.send("肉包子")
21         c2.send(i)
22 
23 producer()
View Code

三、装饰器

python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数。使用装饰器的好处就是可以在不用更改原函数的代码前提下为原函数增加新的功能(例如:权限校验、用户认证、日志记录、性能测试、事务处理、缓存等)

3.1 函数定义

1 def foo(num):
2     return num + 1

可以这么理解:上面定义了一个函数,名字叫做 foo ,也可以把 foo 理解为变量名,该变量指向一个函数对象,如下图所示。

调用函数只需要给函数名加上括号,并传递必要的参数

1 value = foo(3)
2 print(value)

变量名foo现在指向 <function foo at 0x0000000001CE2EA0> 函数对象,但他也可以执行另外一个对象

1 def bar():
2     print("bar")
3 foo = bar
4 foo()
5 bar()

帮助理解的结构图如下

3.2函数作为返回值

在python中一切皆为对象,函数也不例外,它可以像整数一样作为其他函数的返回值,例如:

 1 def foo():
 2     return 1
 3 
 4 def bar():
 5     return foo
 6 
 7 print(bar())   #<function foo at 0x0000000002052EA0>
 8 
 9 print(bar()())
10 #等价于
11 print(foo())

调用函数 bar()  的返回值是一个函数对象 <function foo at 0x0000000002052EA0> ,因为返回值是一个函数,所以可以继续对返回值进行调用。调用函数就是在函数名后面加上括号

帮助理解的结构图如下

3.3 函数作为参数

函数还可以像整体一样作为函数的参数,例如:

1 def foo(num):
2     return num + 1
3 
4 def bar(fun):         #fun = foo
5     return fun(3)
6 
7 value = bar(foo)
8 print(value)

函数 bar 接收一个参数,这个参数是一个可被调用的函数对象,把函数 foo 传递到 bar 中去时, foo 和 fun 两个变量名都指向同一个函数对象

 

3.4 函数嵌套 

1 def outer():
2     x = 1
3     def inner():
4         print(x)
5     inner()
6 
7 outer()

inner作为嵌套的函数,可以访问外部的函数变量,调用outer函数发生了3件事:

  给 变量x 赋值为 1

  定义嵌套函数 inner,此时不会执行 inner 中的代码,应该该函数还没被调用

  调用 inner 函数,执行inner 中的代码

3.5 闭包

1 def outer(x):
2     def inner():
3         print(x)
4 
5     return inner
6 
7 closure = outer(1)
8 closure()

稍微改动上一步骤的函数,把局部变量x 作为参数传递进来,嵌套函数不在直接在函数里被调用,而是作为返回值返回,这里的 closure 就是一个闭包,本质上它还是函数,闭包是引用了自由变量x 的函数inner

3.6 简易的装饰器

 1 def foo():
 2     print("foo")
 3 
 4 #需求,在执行该函数时加上日志
 5 #方法1 --该方法需要修改 foo 函数源代码,不可取
 6 #def foo():
 7 #    print("日志开始")
 8 #    print("foo")
 9 #    print("日志结束")
10 
11 #简单的装饰器
12 def outer(func):
13     def inner():
14         print("日志开始")
15         func()       #业务函数
16         print("日志结束")
17     return inner
18 
19 def foo():
20     print("foo")
21 
22 foo = outer(foo)
23 foo()

这里的 outer 函数其实就是一个装饰器,装饰器是一个带有函数作为参数并返回一个新的函数的闭包,本质上装饰器也是函数。

outer 函数的返回值就是 inner 函数,在 inner 函数中,除了执行日志操作意外,还有业务代码,该函数重新赋值给 foo 变量,调用 foo() 就相当于调用 inner()

foo 重新赋值以前:

重新赋值以后 foo = outer(foo)

3.7 使用装饰器语法糖

这里的 @outer 就相当于  foo = outer(foo)

 1 def outer(func):
 2     def inner():
 3         print("日志开始")
 4         func()       #业务函数
 5         print("日志结束")
 6     return inner
 7 
 8 @outer
 9 def foo():
10     print("foo")
11 
12 foo()

3.8 被装饰的函数带有参数

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 
 4 def outer(fun):
 5     def inner(a,b):
 6         print("日志开始")
 7         fun(a,b)    #业务代码
 8         print("日志结束")
 9     return inner
10 
11 @outer
12 def foo(a,b):
13     print("%s foo %s " %(a,b))
14 
15 foo(3,4)

3.9 被装饰的函数带有不定参数

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 
 4 def outer(fun):
 5     def inner(*args,**kw):
 6         print("日志开始")
 7         fun(*args,**kw)    #业务代码
 8         print("日志结束")
 9     return inner
10 
11 @outer
12 def foo(a,b):
13     print("%s foo %s " %(a,b))
14 
15 @outer
16 def f1(a,b,c):
17     print("%s f1 %s %s "%(a,b,c))
18 
19 foo(3,4)
20 print("-"*30)
21 f1(3,4,5)

4.0 多个装饰器

 1 #!/usr/bin/env python3
 2 #author:Alnk
 3 
 4 def outer1(fun):
 5     def inner(*args,**kw):
 6         print("日志开始")
 7         fun(*args,**kw)    #业务代码
 8         print("日志结束")
 9     return inner
10 
11 def outer2(fun):
12     def inner(*args, **kw):
13         print("我是第2个装饰啊")
14         fun(*args, **kw)  # 业务代码
15         print("第2个装饰器完工")
16     return inner
17 
18 def outer3(fun):
19     def inner(*args, **kw):
20         print("我是第3个装饰啊")
21         fun(*args, **kw)  # 业务代码
22         print("第3个装饰器完工")
23     return inner
24 
25 @outer1
26 @outer2
27 @outer3
28 def foo(a,b):
29     print("%s foo %s " %(a,b))
30 
31 foo(3,4)
32 '''
33 执行完结果如下:
34 日志开始
35 我是第2个装饰啊
36 我是第3个装饰啊
37 3 foo 4 
38 第3个装饰器完工
39 第2个装饰器完工
40 日志结束
41 '''

四、递归函数

 pass

五、简单的算法(二分查找,二维数组)

 pass

六、正则表达式基础

pass 

猜你喜欢

转载自www.cnblogs.com/lichengguo/p/9203064.html