yield expression in the form of functional programming python learning Detailed

Foreword

yield of the English word meaning production, new to Python's time was very confused, has not figure out yield usage. Recently re-learn the next, so finishing the following article, we learn for themselves and their reference, the following did not talk much to say, to take a look at the detailed introduction.

First look at an example

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
 
g = foo()
next(g)

In the above example, because the yield keyword has the function foo, so foo () function g execution result is a generator, then you can use the Next (g) or g. Next () method performs the trigger generator

Results of the implementation of

starting...

When using the next (g) trigger the execution of the generator, the program executed in the normal order from the top down, yield encountered, the program will be suspended
, and the yield values are returned back contact

Print next (g) of the results

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
 
g = foo()
print(next(g))

Program execution results

starting...
None

In the example above, perform a next (g) method, the program pauses in yield that line, then call the next (g) again, the program will continue to run down the line from the yield statement

Modify the code above, calling several times more than the next method, and printing method returns the next result

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))

The above results of the implementation of this code is

starting...
None
********************
res: None
None

We can see, the program is actually running step by step conjecture, but the above program also has a very significant drawback: it is the above code does not have any practical significance: the value of the res is always None

In the actual development, the purpose of the form is the expression yield can get a yield value and yield this value is assigned to a variable, so have actual meaning

How it should operate in order to assign a value to a variable res it? ? That is to call generator itself send method

send method triggers a generator perform, while also pass parameters to yield the send method
to modify the above code

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
g = foo()
next(g)
print(g.send(5))

Results of the implementation of:

starting...
res: 5
None

To analyze the execution of the above code:

  1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g.
  2.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环
  3.程序遇到yield关键字,程序暂停,此时next(g)语句执行完成
  4.程序执行g.send(5),程序会从yield关键字那一行继续向下运行,send会把5这个值传递给yield
  5.yield接收到send方法传递过来的值,然后由yield赋值给res变量
  6.由于send方法中包含next()方法,所以程序会继续向下运行执行print方法,然后再次进入while循环
  7.程序执行再次遇到yield关键字,yield会返回后面的值,由于yield后面没有接任何参数,所以yield会返回None,程序再次暂停,直到再次调用next方法或send方法

Modify the code, call the send method multiple times

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
g = foo()
next(g)
print(g.send(5))
print("*"*20)
print(g.send(10))
print("#"*20)
print(g.send(15))

Executing a program, the following results

starting...
res: 5
None
********************
res: 10
None
####################
res: 15
None

It can be seen as the execution process of the above code performs the same operation above analysis

In the example above, if the call to send method, passing parameters to None, the results obtained will be like it? ?

From the above analysis, it is possible to know:

If the g.send()method of transmitting the parameters to yield keyword is None, then the yield value passed to the key variable to be None res
For the latter did not take any value would yield, the default value is also returned to None yield, so the program execution result will be a None two
modify the code to verify the above conjecture

def foo():
 print("starting...")
 while True:
  res = yield
  print("res:",res)
g = foo()
next(g)
print("#"*20)
print(g.send(None))

View the results of the program

starting...
####################
res: None
None

As can be seen from the execution result of the program, if the method of a producer call to send, parameters passed as None, the result will be two programs executed None

Use the form to achieve expression yield linux system "grep -rl root / etc" command

code show as below:

import os
def init(func):
 def wrapper(*args, **kwargs):
  g = func(*args, **kwargs)
  next(g)
  return g
 return wrapper
@init
def get_file_path(target):
 """
 get file abspath
 # 阶段一:递归找文件的绝对路径,把文件的完事路径发送给阶段二
 :param target:
 :return:
 """
 while True:
  start_path = yield
  g = os.walk(start_path)
  for parent_dir, _, files in g:
   for file in files:
    file_path = r"%s\%s" % (parent_dir, file)
    target.send(file_path)
@init
def opener(target):
 """
 get file obj
 # 阶段二:收到文件的完整路径,打开文件获取文件对象,把文件对象发送给阶段三
 :param target:
 :return:
 """
 while True:
  file_path = yield
  with open(file_path, encoding='utf-8') as f:
   target.send((file_path, f))
@init
def cat_file(target):
 """
 read file content
 # 阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四
 :param target:
 :return:
 """
 while True:
  file_path, f = yield
  for line in f:
   file_content = target.send((file_path, line))
   if file_content:
    break
@init
def grep(target, pattern):
 """
 grep function
 # 阶段四:收到文件的一行内容,判断要查找的内容是否在这一行中,如果在,则把文件名发送给阶段五
 :param target:
 :param pattern:
 :return:
 """
 tag = False
 while True:
  file_path, line = yield tag
  tag = False
  if pattern in line:
   target.send(file_path)
   tag = True
@init
def printer():
 """
 print file name
 # 阶段五:收到文件名,打印结果
 :return:
 """
 while True:
  filename = yield
  print(filename)
path1 = "/root"   # 定义要搜索的路径
path2 = "/etc"   # 定义要搜索的路径
g = get_file_path(opener(cat_file(grep(printer(), "root"))))
print(g)
g.send(path1)
g.send(path2)

We recommend learning Python buckle qun: 774711191, look at how seniors are learning! From basic web development python script to, reptiles, django, data mining, etc. [PDF, actual source code], zero-based projects to combat data are finishing. Given to every little python partner! Every day, Daniel explain the timing Python technology, to share some of the ways to learn and need to pay attention to small details, click Join our learners python gathering
summary

That's all for this article, I hope the contents of this paper has some reference value of learning for everyone to learn or work

Published 44 original articles · won praise 56 · views 60000 +

Guess you like

Origin blog.csdn.net/haoxun10/article/details/104908500