Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Python Day4

$
0
0

本章内容:

1.高阶函数和嵌套函数回顾

2.装饰器

3.生成器

4迭代器

什么是高阶函数?

高阶函数代表函数作为一个值来进行调用,也称为函数调用函数


def bar():
print("123")
def func(d):
print("hello ")
func(bar())
什么是嵌套函数? 嵌套函数就是指的函数套函数
def bar():
def func():
print("hello")
return func()
bar()
二.装饰器

装饰器:

装饰器:本质是函数 (装饰其他函数)

定义 给其他函数添加新功能

原则1 不能修改被装饰函数的源代码

2 不能修改被装饰的函数调用方式

函数即变量:
def a():
print("hello")
b=a
b()
View Code 实现装饰器需要的功能: 高阶函数+嵌套函数=装饰器
# _author_=AbeoHu
#首先先来定义个函数
import time
#如果我要在test1基础上添加新的功能,把运行时间打印出来
#那么我们首先先来定义个打印时间的函数
def deco():
start_time=time.time()
stop_time=time.time()
print("运行了%s"%(stop_time-start_time))
#怎么将这两个函数结合起来,实现装饰器功能?嵌套函数:
def timeer(func):
def deco():
start_time=time.time()
func()#打印func,等于运行下面的test1函数func=test1
stop_time=time.time()
print("运行了%s"%(stop_time-start_time))
return deco#返回值
@timeer#代替了变量
def test1():
time.sleep(3)
print("hello")
test1()
View Code

二.生成器

列表生成式

列表生成式即List Comprehensions,是python内置的非常简单却强大的可以用来创建list的生成式。

举个例子,比如你要生成1-11的数据,可以用range(11)


>>> [ i for i in range(11)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
如果我们要循环1*1,2*2怎么做? 方法一:循环
>>> [ i for i in range(11)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> L=[]
>>> for x in range(1,11):
... L.append(x*x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是这样做会有点麻烦,那么用列表生成式我们就可以代替
>>> [ x*x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
小结 运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁

生成器:

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。 创建个生成器很简单,第一种方法,将列表生成式的[]改成():
>>> ( x*x for x in range(1,11))
<generator object <genexpr> at 0x0000028213CFB2B0>

那么我们如何打印生成器的参数呢?

next


>>> g = ( x*x for x in range(1,11))
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9

generator保存的是算法,每次调用 next(g) ,就计算出 g 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的错误。

著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
fib(10)
可以看出, fib 函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。 也就是说,上面的函数和generator仅一步之遥。要把 fib 函数变成generator,只需要把 print(b) 改为 yield b 就可以了:
# _author_=AbeoHu
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
f = fib(6)
print(next(f))
print(next(f))
print(next(f))
generator和函数的执行流程不一样。函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。 那么我们用生成器来实现一个单线程:
# _author_=AbeoHu
import time
def coun(name):
print("%s,准备吃包子了"%(name))
while True:
baozi=yield
print("包子%s来了,被%s吃了"%(baozi,name))
c = coun("AbeoHu")
c.__next__()#打印到yield停下来
c.__next__()#下次打印会继续按照照这个打印
c.send("韭菜")#传参,等于将韭菜值传给了yield,也就是baozi=”韭菜“
def pro(name):
c = coun('AbeoHu')
c1 = coun('b')
c.__next__()
c1.__next__()
print("我开始做包子了")
for i in range(10):
time.sleep(1)
print("做了一个包子,分凉拌")
c.send(i)
c1.send(i)
pro("AbeoHu")
View Code

Viewing all articles
Browse latest Browse all 9596

Trending Articles