zoukankan      html  css  js  c++  java
  • 22、yield表达式形式和面向过程编程

    一 yield的表达式

    def foo():
        print('starting')
        while True:
            x=yield None#return 2
            print('value :',x)
    g=foo()
    print(next(g))
    print(g.send(2))
    
    运行结果:
    starting  #运行函数,打印starting后碰到yield停住
    None    #next()触发后 yield将None赋值给x,打印None后循环碰到yield停住
    value : 2  #g.send(2)将2赋值给yield,yield将2赋值给x,继续循环打印出2碰到yield停住
    None      #碰到yield停住并返回None,print的结果就是None

     以上将yield接受到的值赋值给了x,这样形式就叫做yield的表达式形式。

    函数foo中有yield,那它就是迭代器。可以使用next()。yield可以返回结果,默认为None。

    g.send()前生成器必须先next一次才能发送值。所以写一个装饰器,让foo自动next一次。

    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    
    @init #foo=init(foo)
    def foo():
        print('starting')
        while True:
            x=yield
            print('value :',x)
    g=foo() #wrapper()
    g.send(2)
    
    运行结果:
    starting
    value :2

    send的效果:
    1:先从为暂停位置的那个yield传一个值,然后yield会把值赋值x
    2:与next的功能一样

    # _*_ coding:utf-8 _*_
    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    @init
    def eater(name):
        print('%s ready to eat'%name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food)
            print('%s start to eat %s'%(name,food))
    
    e=eater('alex')
    print(e.send('food1'))
    print(e.send('food2'))
    print(e.send('food3'))
    
    运行结果:
    alex ready to eat
    alex start to eat food1
    ['food1']
    alex start to eat food2
    ['food1', 'food2']
    alex start to eat food3
    ['food1', 'food2', 'food3']

    二、面向过程编程

    应用:grep -rl 'root'  /etc

    实现打印出/etc目录下所有包含‘root’的文件的文件路径

    分析完成功能的阶段:

    阶段一:递归地找出目录下所有文件的绝对路径,把路径发给阶段二

    阶段二:收到文件路径,打开文件获取文件对象,把文件对象发给阶段三

    阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四

    阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五

    阶段五:收到文件名,打印结果

    import os
    #装饰器,自动next()
    def init(func):
        def wrapper(*args,**kwargs):
            g = func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    #j阶段一:递归地找出目录下所有文件的绝对路径,把路径发给阶段二
    @init
    def search(target):
        'search file abspath'
        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):
        while True:
            file_path = yield
            with open(file_path,encoding = 'utf-8') as f:
                target.send((file_path,f))
    #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四
    @init
    def cat(target):
        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):
        tag=False
        while True:
            filepath,line=yield tag
            tag=False
            if pattern in line:
                target.send(filepath)
                tag=True
    #阶段五:收到文件名,打印结果
    @init
    def printer():
        while True:
            filename = yield
            print(filename)
    start_path = r'E:PycharmProjectsqz5day9'
    # search(opener(cat(grep(printer(),'Jack'))),start_path)
    g=search(opener(cat(grep(printer(),'Jack'))))
    g.send(start_path)
  • 相关阅读:
    Java Web系统经常使用的第三方接口
    ExtJS笔记--applyTo和renderTo的差别
    ORACLE触发器具体解释
    java多线程样例
    RapeLay(电车之狼R)的结局介绍 (隐藏结局攻略)
    排序——选择排序
    常见hash算法的原理
    jdk和jre是什么?都有什么用?(转帖)
    Ubuntu下deb包的安装方法
    參加《全流程全要素的研发项目管理》培训记录与心得
  • 原文地址:https://www.cnblogs.com/f1443526266/p/7054484.html
Copyright © 2011-2022 走看看