python--表达式形式的yield、面向过程编程、内置函数

yield的表达式形式

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 None#return 1
        print('value :   ', x)

g = foo() #wrapper()

g.send(2)
结果:
starting
value :    2

send的效果:
     1:先从为暂停位置的那个yield传一个值,然后yield会把值赋值x
     2:与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 None#return 1
        print('value :   ', x)
#
g = foo() #wrapper()

print(g)
next(g)
print('='*30)
print(g.send(1))
print('='*30)
print(g.send(None)) #g.send(None)等同于next(g)
结果:
starting
<generator object foo at 0x0000000002144990>
value :    None
==============================
value :    1
None
==============================
value :    None
None
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#return None
        food_list.append(food)
        print('%s start to eat %s' % (name, food))


e = eater('alex')
print(e.send('狗屎'))
print(e.send('猫屎'))
print(e.send('alex屎'))
结果:
alex ready to eat
alex start to eat 狗屎
['狗屎']
alex start to eat 猫屎
['狗屎', '猫屎']
alex start to eat alex屎
['狗屎', '猫屎', 'alex屎']
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#return None
        food_list.append(food)
        print('%s start to eat %s' % (name, food))

def make_shit(people, n):
    for i in range(n):
        people.send('shit%s' % i)

e = eater('alex')
make_shit(e, 5)
结果:
alex ready to eat
alex start to eat shit0
alex start to eat shit1
alex start to eat shit2
alex start to eat shit3
alex start to eat shit4

应用:grep -rl 'root' /etc

import os
def init(func):
    def wrapper(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)
        return g
    return wrapper
#阶段一:递归地找文件的绝对路径,把路径发给阶段二
def search(target,start_path):
    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:
        filepath,f = yield
        for line in f:
            target.send((filepath, line))
#阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五
@init
def grep(target, pattern):
    while True:
        filepath,line = yield
        if pattern in line:
            target.send(filepath)
#阶段五:收到文件名,打印结果
@init
def printer():
    while True:
        filename = yield
        print(filename)

start_path = r'C:\Users\Administrator\PycharmProjects\untitled4\a'
search(opener(cat(grep(printer(), 'root'))), start_path)
结果:
C:\Users\Administrator\PycharmProjects\untitled4\a\a.txt
C:\Users\Administrator\PycharmProjects\untitled4\a\b\b2.txt
C:\Users\Administrator\PycharmProjects\untitled4\a\b\c\c.txt

进一步优化版本:

import os
def init(func):
    def wrapper(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)
        return g
    return wrapper
#阶段一:递归地找文件的绝对路径,把路径发给阶段二
@init
def search(target):
    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:
        filepath, f = yield
        for line in f:
            res = target.send((filepath, 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_path1 = r'C:\Users\Administrator\PycharmProjects\untitled4\a'
start_path2 = r'C:\Users\Administrator\PycharmProjects\untitled4\a\b'
g = search(opener(cat(grep(printer(), 'root'))))

print(g)
# g.send(start_path1)
g.send(start_path2)
结果:
<generator object search at 0x0000000001E04DB0>
C:\Users\Administrator\PycharmProjects\untitled4\a\b\b2.txt
C:\Users\Administrator\PycharmProjects\untitled4\a\b\c\c.txt
<generator object search at 0x0000000001E97048>
def init(func):
    def wrapper(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)
        return g
    return wrapper
@init  #func=init(func)
def func():
    tag = False
    while True:
        x = yield tag #g.send('b') #x='b'
        tag = False
        if 'root' in x:
            print(x)
            tag = True
g = func()

print(g.send('a'))
print(g.send('root123'))
print(g.send('b'))
print(g.send('c'))
print(g.send('d'))
print(g.send('e'))
结果:
False
root123
True
False
False
False
False

内置函数

print(abs(-9))
print(all([1, 2, 3, 4]))
print(all([1, 2, 3, 0]))
print(all([1, 2, 3, None]))
print(all([1, 2, 3, '']))
print(all([]))
结果:
9
True
False
False
False
True
print(all(i for i in range(1, 3)))
print(any(''))
print(any([0, '', {}, (), 1]))
结果:
True
False
True
print(bin(3)) #将十进制数转换为二进制数
print(oct(9)) #将十进制数转换为八进制
print(hex(13)) #将十进制数转换为十六进制
结果:
0b11
0o11
0xd
print(bool(0))
print(bool(None))
print(bool(''))
结果:
False
False
False
print(bytes('sss', encoding='utf-8'))
print('sss'.encode('utf-8'))
结果:
b'sss'
b'sss'
def func():
    pass
print(callable(func))  #查看函数是否可以被调用
结果:
True
print(chr(66)) #返回对象对应的ASCII字符
print(ord('B')) #与chr相反,返回ASCII字符对应的内容
结果:
B
66
x = complex(1-2j) #complex()是复数函数
print(x.real) #查看实部
print(x.imag) #查看虚部
结果:
1.0
-2.0

面向对象的内置函数:

classmethod

staticmethod

property

 

setattr

delattr

getattr

hasattr

还有:

  • int
  • dict
  • list
  • tuple
  • set
  • str
import os
#
print(dir(os)) #os.walk

print(help(os))

def func():
    'my function'
    pass

print(help(func))

 补充

import time
import random
def init(func):
    def wrapper(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)
        return g
    return wrapper

def producer(target,count):
    for i in range(count):
        time.sleep(random.randrange(1, 4))
        x = 'baozi%s' % i
        print('\033[45m 厨师造好的包子: %s\033[0m' % x)
        target.send(x)

@init
def consumer(name):
    while True:
        food = yield
        time.sleep(random.randrange(1, 4))
        print('\033[46m %s start to eat %s \033[0m' % (name, food))

producer(consumer('alex'), 10)
结果:
 厨师造好的包子: baozi0
 alex start to eat baozi0 
.
.
.
 厨师造好的包子: baozi9
 alex start to eat baozi9 

 下面为不用yield的版本:

import time
import random

def producer(count):
    res = []
    for i in range(count):
        res.append('baozi %s' %i)
    return res

def consumer(name,res):
    for i in res:
        print('%s start to eat %s' % (name, i))

consumer('alex',producer(10))
结果:
alex start to eat baozi 0
alex start to eat baozi 1
.
.
.
alex start to eat baozi 8
alex start to eat baozi 9

       虽然两者都可以实现,但是用yield的程序是:厨师做好一个包子,alex吃一个包子,而不用yield的版本是:厨师做好十个包子之后alex才吃。单是此程序体现的差别,往大方面考虑,涉及内存问题,显然yield版本比较省内存,所以我们建议使用yield版本。

posted @ 2017-06-19 19:04  始怡  阅读(210)  评论(0编辑  收藏  举报