今日概要:
1、内置模块
2、协程函数
3、递归
4、面向过程编程与函数编程
5、模块
6、包
7、re正则
一、内置模块
1、匿名函数lambda
定义:匿名函数通常是创建了可以被调用的函数,它返回了函数,而并没有将这个函数命名
#不使用匿名函数 def func(x,y): return x+y func(1,2) #使用匿名函数 f=lambda x,y:x+y print(f(1,2))
2、max,zip(拉链函数),sorted用法
age={ ‘dragon‘:18, ‘panda‘:20, ‘banana‘:21, ‘lili‘:30 } print(max(age)) #默认是以字典的key进行排序,key如果是字符串就按照首位顺序,首位如果一致,一次递归比较 #方法一,用zip将key和values反转 res=zip(age.values(),age.keys()) print(max(res))
def foo(k): return age[k] print(max(age,key=foo)) print(max(age,key=lambda k:age[k])) print(min(age,key=lambda k:age[k])) print(sorted(age)) #默认的排序结果是从小到大 print(sorted(age,key=lambda x:age[x])) #默认的排序结果是从小到大 print(sorted(age,key=lambda x:age[x],reverse=True)) #默认的排序结果是从小到大,resverse反转从大到小
3、map,reduce,filter
1、map
#map,将lambda函数对应的关系映射到列表里 l=[‘dragon‘,‘banana‘,‘water‘] res=map(lambda x:x+‘_guess‘,l) print(res) #返回值为迭代器 print (list(res))
2、reduce
#1、默认不加参数,从列表中取出一个值当作元素,然后依次取出第二个值到最后依次与第一个元素做运算,最终得出最后的值 #2、加参数后就从参数中取第一个值 from functools import reduce l=[1,2,3,4,5] print(reduce(lambda x,y:x+y,l,10))
3、filter
#filter过滤规则,将匹配的元素提取出来 l=[‘test123‘,‘goto123‘,‘run123‘,‘pass‘] res=filter(lambda x:x.endswith(‘123‘),l) print(list(res))
二、协程函数
python由于GIL的原因,导致其线程无法发挥多核的并行计算能力(后来有了multiprocessing,可以实现多进程并行),显得比较鸡肋。既然在GIL之下,同一时刻只能有一个线程在运行,那么对于CPU密集的程序来说,线程之间的切换开销就成了拖累,而以I/O为瓶颈的程序正是协程所擅长的:多任务并发(非并行),每个任务在合适的时候挂起(发起I/O)和恢复(I/O结束)
#!/usr/bin/python # -*- coding:utf-8 -*- #例子: def f1(func): def f2(*args,**kwargs): g = func(*args,**kwargs) next(g) return g return f2 @f1 def eater(name): print (‘%s ready to eat‘ %(name)) while True: food = yield print (‘%s,%s‘ %(name,food)) g = eater(‘alex‘) g.send(‘jjj‘)
三、递归
定义:在函数调用过程中,直接或间接地调用了函数本身,这就是函数的递归调用
notice:python默认最大递归数为1000,sys.getrecursionlimit()查看
l = list(range(1000)) def to(info,g): if len(info) == 0: print (‘not exit‘) return mid = int(len(info)/2) if info[mid] > g: print (‘%s‘ %(info[0:mid])) to(info[0:mid],g) elif info[mid] < g: print (‘%s‘ %(info[mid+1:])) to(info[mid+1:],g) elif info[mid] == g: print (info[mid]) to(l,25)
四、面向过程
定义:面向过程程序设计:是一种流水线式的变成思路,是机械式
优点:程序结构清晰,可以把复杂的问题简单化
缺点:扩展性差
适用场景:
git程序,httpd服务,linux内核
import os #1、定义一个初始化yield的装饰器 def init(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) next(res) return res return wrapper #第一步先遍历目录 @init def search(target): while True: search_path=yield g=os.walk(search_path) for par_dir,_,files in g: for file in files: file_abs_path=r‘%s\%s‘ %(par_dir,file) # print(file_abs_path) target.send(file_abs_path) #第二步打开文件 @init def opener(target): while True: file_abs_path=yield # print(‘opener func==>‘,file_abs_path) with open(file_abs_path,encoding=‘utf-8‘) as f: target.send((file_abs_path,f)) #第三步读文件里的行 @init def cat(target): while True: file_abs_path,f=yield #(file_abs_path,f) for line in f: tag=target.send((file_abs_path,line)) if tag: break #第四步进行grep过滤,如果第一次存在,则跳过该文件,进入下一次文件判断 @init def grep(target,pattern): tag=False while True: file_abs_path,line=yield tag tag=False if pattern in line: tag=True target.send(file_abs_path) #第五步,打印匹配内容的文件名 @init def printer(): while True: file_abs_path=yield print(file_abs_path) x=r‘路径‘ g=search(opener(cat(grep(printer(),‘python‘)))) print(g) g.send(x)
五、模块
1、import导入模块
产生新的名称空间,以新建的名称空间为全局名称空间,执行文件的代码,拿到一个模块名,执行模块名.py产生的名称空间
2、from ... import ...
产生新的名称空间,以新建的名称空间为全局名称空间,执行文件的代码,直接拿到就是模块名.py产生的名称空间中名字
优点:方便不用添加前缀
缺点:容易跟当前文件的名称空间冲突
3、模块的搜索顺序:
内存---->内置---->sys.path
4