首页 > 代码库 > 生成器、三元运算符、面向过程

生成器、三元运算符、面向过程

生成器:
函数内部有 yield 关键字,该函数执行的结果就是生成器函数,yield后跟返回值,不跟是None
生成器本质就是迭代器
 
def foo();
     print(‘start‘)
     yield   # yield  ok     #可跟返回值
     print(‘end‘)
g=foo()          # g 就是生成器
 
res=g.__next__()    #  next 执行一次
 
如上代码:
     函数碰到return结束,这里的yield相当于return,后面没有跟返回值,返回None
     同一个生成器的话,碰到yield 暂停,再次执行next时,继续向下执行,重新生成器的话就重新开始了
 
yield表达式形式:
 
def foo():
     print(‘start‘)
   while Ture:
     x=yield                    #返回值的  None(没有值,没有意义)
     print(x)                   # x 是 yiled给的值,x 没有值  是None
g=foo()
print(g)
next(g)
 
#######执行结果是生成器,也就是g, next(g)执行一次,打印  start ,  碰到 yield 然后暂停,把返回值返回(None);
                                   再next一下,从暂停位置进行,打印x,在进入循环,碰到yield 暂停,把返回值返回
 
 
X没有值就失去了表达式的意义,如何给 X  传值呢??
def foo():
     print(‘start‘)
   while Ture:
     x=yield                    #返回值的  None(没有值,没有意义)     #  g.send(1)
     print(x)                   # x 是 yiled给的值,x 没有值  是None
g=foo()
print(g)
next(g)
g.send(1)         
                     #跟 next 效果一样,都是触发函数继续进行的功能,但是 send 还有一个传值的功能
 
      运行: 第一次 next(g) 走到了 yield 的时候暂停;然后进行 g.send(1),走之前会从暂停位置把 1 传给 yiled ,然后 yield 把值赋值给 X,然后继续往下走
X有值了,然后打印 X;然后再循环到 yield ,这时候就不传值了(send就是在开始阶段传值,后面就只有 next的功能),是返回值,但是X是有值的
          
注意:生成器是表达式形式的话,必须先send (None),在send其他值,或者先next()一下,在进行send
          意思是必须得先让其做一个初始化,让其走到一个暂停的位置,因为send是基于 yield 在暂停的情况来传值的
 
yield功能:
     1.相当于把__iter__和__next__方法封装到函数里
     2.与return的功能类似,但是return只能返回一次值,而yoeld可以返回多次
     3.函数暂停与再继续的状态由yiled保存
     
就像linux中的管道 | ,可以隔离两边的命令,把左边的结果给右边
 
生成器模拟tail -f动态获取新增一行:
     思路:
          以读的模式打开一个文件,光标立马跑到最后,进入循环读的过程,读到值返回,没读到重新进入下一次循环
import time                                             #导入time模块
def tail(filepath,encoding=‘utf-8‘):                    #定义函数 tail  传入filepath(文件路径)参数,并默认指定为 utf-8
    with open(filepath,encoding=encoding) as f:         #以读形式打开文件,赋值给 f(encoding等于默认的指定编码)
        f.seek(0,2)                                     # seek 控制光标到末尾,然后再进行读一行操作(以末尾为参照(0,2),光标跑到最后)
        while True:
            line=f.readline()                           # 读一行内容并赋值给 line ,光标移动到这一行的最后
            if line:                                    # if line 判断 line 是不是空的  如果是空的就是False 反之为 Ture
                yield line                              # 返回 line 
            else:
                time.sleep(0.5)
        countue                                          # 没有值的话延迟,再读一次    countue可不加
def grep(lines,pattern):                                # lines 就是tail执行的结果,pattern  是要过滤的内容
    for line in lines:                                   # 就是在for i in tail这个生成器(g),如下,把g1,g2当做参数传入grep,这里就是在循环g
        if pattern in line:
            print(line)
g1=tail(‘a.txt‘)                                        # 用g 拿到生成器
g2=grep(g1,‘error‘)
g3=grep(g2,‘404‘)
for i in g3:                                            #触发生成器的效果
    print(i)
 
 
  三元表达式:   
     条件成立返回的结果         条件       条件不成立返回的结果
 
如下:
x=2
y=3
if x > y:
     print(x)
esle:
     print(y)
 
精简为三元表达式:    res= x if x>y else y          res= ‘aaa‘ if x>y ‘666‘(两边是返回值,可以是任意的)
 
求最大值:
def max2(x,y):
     if x>y:
          return x
     else:
          return y
 
精简:     return x if x>y else y
     print(max2(4,6))
 
 
列表解析:
 
把字符串每个字符取出来大写,存成列表
s=‘hello‘
l=[]
for i in s:
     res=i.upper()
     l.append(res)
print(l)
 
列表解析:
s=‘hello‘
res=[i.upper() for i in s]          #循环遍历 s 成立取出来的 i ,把 i 放到左边执行upper变大写,存入列表中
print(res)
 
 
把大于50的值取出来存入列表:
l=[1,31,73,84,57,22]
l_new=[]
for i in l:
     if i>50:
     l_new.append(i)
print(l_new)
 
列表解析:
l_new=[i for i in l if i>50]     (这里不加else,因为不知道是if 的else 还是for 的else)
print(l_new)
 
 
生成器表达式:
     与列表解析语法一样,但是得到的结果是生成器,别列表解析更省内存
 
l=[ i for i in range(10000000000000000000000000000000000000000000000)]
     这样的话会全部出来,占用内存
 
g=(i for i in range(10000000000000000000000000000000000000000000000))
     拿到的结果是一个生成器(生成器的内存地址)
 
next(g)  就相当于是  g.__next__()   取出一个值,不管多少值,一次只取一个,不会像列表那样撑内存
 
 
表达式形式生成器:
 
x=yield None
 
 
面向过程:
 
     就像是流水线,分一个个的阶段,一整套流程
     核心就是过程,过程就是流程,解决问题的步骤,一步步实现
 
优点:
     思路清晰,把复杂的问题简单化,流程化
缺点:
     中间有一个环节有问题,那么整体就会有问题

生成器、三元运算符、面向过程