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版本。