一、生成器

1、定义:

生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。

也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。

def foo():
    print('first------>')
    yield 1
    print('second----->')
    yield 2
    print('third----->')
    yield 3
    print('fouth----->')


g=foo()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())

# for i in g: #obj=g.__iter__() #obj.__next__()
# print(i)

2、yield的功能:

(1)与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值
(2)为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器
(3)遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的

def countdown(n):
    print('starting countdown')

    while n > 0:
        yield n
        n-=1
    print('stop countdown')
g=countdown(5)
# print(g)
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())

#
# for i in g:
#     print(i)

3、yield的表达式形式

send的效果:

a、先为暂停的那个yield位置传值,然后yield会把值赋给x

b、与next的功能一样

4、生成器函数(计时器)

def countdown(n):
    while n > 0:
        yield n
        n-=1


# g=countdown(5)
# print(g.__next__())
# print(g.__next__())

5、yield表达式的实际应用(查找关键字所包含的目录)——面向过程式编程

#应用:grep -rl 'root' /etc
import os
def init(func):
    def wrapper(*args,**kwargs):
        g=func(*args,**kwargs)
        next(g)
        return g
    return wrapper
#阶段一:递归的找文件的绝对路径,把路径发给阶段二
@init
def search(target):
    'search file ahspath'
    while True:
        start_path=yield
        g=os.walk(start_path)
        for par_dir ,_, files in g:
            for file in files:
                file_path = r'%s\%s' % (par_dir,file)
                target.send(file_path)
#阶段二:收到文件路径,打开文件获取对象,把文件对象发给阶段三
@init
def opener(target):
    'get file obj:f=open(filepath'
    while True:
        file_path=yield
        with open(file_path,encoding='utf-8') as f:
            target.send((file_path,f))
#阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四
@init
def cat(target):
    'read file'
    while True:
        file_path,f = yield
        for line in f:
            res = target.send((file_path,line))
            if res:
                break
#阶段四:收到每一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五
@init
def grep(target,pattern):
    'grep function'
    tag=False
    while True:
        file_path,line=yield tag #target.send((filepath,line))
        tag=False
        if pattern in line:
            target.send(file_path)
            tag = True
#阶段五:收到文件名,打印结果
@init
def printer():
    'print function'
    while True:
        filename=yield
        print(filename)
start_path1=r'D:\py.code\test'
# start_path2=r'D:\py.code\test\test1'
g=search(opener(cat(grep(printer(),'root'))))
# print(g)
g.send(start_path1)

二、列表解析和三元表达式

1、根据已有列表,高效创建新列表的方式。

s='hello'
res=[i.upper() for i in s]
print(res)


# l=[1,31,73,84,57,22]
# l_new=[]
# for i in l:
#     if i > 50:
#         l_new.append(i)
# print(l_new)

res=[i for i in l if i > 50]
print(res)

2、三元表达式

x=2
y=3

if x > y:
    print(x)
else:
    print(y)


res='aaaaa' if x > y else 'bbbbbbb'

print(res)


def max2(x,y):
    if x > y:
        return x
    else:
        return y

    return x if x > y else y

print(max2(1,2))                            

 

posted on 2017-06-19 16:30  枫凌01  阅读(369)  评论(0编辑  收藏  举报