装饰器、迭代器、生成器、正则匹配
装饰器
个人对装饰器的理解如下:
1 ''' 2 装饰器:不改变源代码和调用方式前提下,添加需求 3 知识点:高阶函数、函数嵌套 4 ''' 5 def pay(func): 6 def inner(*args,**kwargs): 7 print("已支付") 8 func(*args,**kwargs) 9 return inner 10 def add_func(func): 11 def inner(*args,**kwargs): 12 print("我是装饰器") 13 func(*args,**kwargs)#*args,**kwargs表示不定值传参,意思是可以有,可以没有 14 return inner #此处应用嵌套函数实现返回函数内存地址 15 16 @add_func 17 @pay 18 def run_func1(level): 19 if level>3: 20 print("解锁高级玩法") 21 @add_func 22 def run_func2(): 23 print("普通玩家") 24 # run_func1 = add_func(run_func1)#高阶函数,传值 25 # run_func2 = add_func(run_func2)#高阶函数,传值 26 run_func1(4) 27 run_func2()
装饰器就是用@格式添加在要执行函数体头部的一种语法,用于添加新功能。
迭代器&生成器
迭代器
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
1 a = iter([1,2,3]) 2 print(a.__next__()) 3 print(a.__next__()) 4 print(a.__next__())
输出结果:1 2 3
生成器
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
生成斐波那契额数列:
1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: 4 yield b 5 #含有yield关键字即为生成器 6 # yield即保存当前运行的值,留给next调用 7 a, b = b, a + b 8 n = n + 1 9 return "结束!" #此处的return表示抛出异常 10 # fib(10) 11 # print(fib(10)) 12 f = fib(10) 13 print(f.__next__()) 14 print(f.__next__()) 15 print(f.__next__()) 16 print(f.__next__())
作用:
这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另外,还可通过yield实现在单线程的情况下实现并发运算的效果,即生成器并行的概念。
代码如下:
1 ''' 2 用吃包子事件来模拟最简单的并发模式 3 ''' 4 import time 5 def consume(name): 6 print("%s 准备吃包子咯"%name) 7 while True: 8 baozi = yield 9 10 print("包子[%s]来了,被[%s]吃了!"%(baozi,name)) 11 12 def producer(name): 13 c = consume('顾客一') 14 c2 = consume('顾客二') 15 c.__next__() 16 c2.__next__() 17 print("开始做包子咯!") 18 count = 0 19 for i in range(10): 20 time.sleep(1) 21 print("做了2个包子") 22 c.send(i) 23 c2.send(i) 24 count=count+2 25 print("强强已经做了%s个包子"%count) 26 producer('强强')
算法基础
二分查找:
1 ''' 2 通过二分查找:找出67的位置 3 ''' 4 def binary_search(data_list, find_num): 5 mid_pos = int(len(data_list) / 2) # find the middle position of the list 6 mid_val = data_list[mid_pos] # get the value by it's position 7 print(data_list) 8 if len(data_list) > 1: 9 if mid_val > find_num: # means the find_num is in left hand of mid_val 10 print("[%s] should be in left of [%s]" % (find_num, mid_val)) 11 binary_search(data_list[:mid_pos], find_num) 12 elif mid_val < find_num: # means the find_num is in the right hand of mid_val 13 print("[%s] should be in right of [%s]" % (find_num, mid_val)) 14 binary_search(data_list[mid_pos:], find_num) 15 else: # means the mid_val == find_num 16 print("Find ", find_num) 17 18 else: 19 print("cannot find [%s] in data_list" % find_num) 20 21 22 if __name__ == '__main__': 23 primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 24 binary_search(primes, 67)
冒泡排序:
1 ''' 2 将一个乱序数组按顺序排列 3 ''' 4 data = [10, 4, 33, 21, 54, 3, 8, 11, 5, 22, 2, 1, 17, 13, 6] 5 6 print("before sort:", data) 7 8 previous = data[0] 9 for j in range(len(data)): 10 tmp = 0 11 for i in range(len(data) - 1): 12 if data[i] > data[i + 1]: 13 tmp = data[i] 14 data[i] = data[i + 1] 15 data[i + 1] = tmp 16 17 print("after sort:", data)
正则表达式
1 ''' 2 第一步:import re 3 导入正则模块 4 第二步:m = re.search('^[0-9]','14534Abc') 5 用search方法去用^[0-9]规则去匹配后面的字符串,将符合规则的字符传入m 6 第三步:print(m.group()) 7 m.group()返回匹配上的结果,此处为1,因为匹配上的是1这个字符
else:
8 print("doesn't match.")
9 10 ''' 11 import re 12 m = re.search('^[0-9]','14534Abc') 13 print(m.group())
几个常见正则匹配例子
1 # 匹配手机号 2 3 phone_str = "hey my name is alex, and my phone number is 13651054607, please call me if you are pretty!" 4 phone_str2 = "hey my name is alex, and my phone number is 18651054604, please call me if you are pretty!" 5 6 m = re.search("(1)([358]\d{9})", phone_str2) 7 if m: 8 print(m.group()) 9 10 # 匹配IPV4 11 12 ip_addr = "inet 192.168.60.223 netmask 0xffffff00 broadcast 192.168.60.255" 13 14 m = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ip_addr) 15 16 print(m.group()) 17 18 # 分组匹配地址 19 20 contactInfo = 'Oldboy School, Beijing Changping Shahe: 010-8343245' 21 match = re.search(r'(\w+), (\w+): (\S+)', contactInfo) # 分组 22 """ 23 >>> match.group(1) 24 'Doe' 25 >>> match.group(2) 26 'John' 27 >>> match.group(3) 28 '555-1212' 29 """ 30 match = re.search(r'(?P\w+), (?P ', contactInfo) 31 """ 32 >>> match.group('last') 33 'Doe' 34 >>> match.group('first') 35 'John' 36 >>> match.group('phone') 37 '555-1212' 38 """ 39 40 # 匹配email 41 42 email = "alex.li@126.com http://www.oldboyedu.com" 43 44 m = re.search(r"[0-9.a-z]{0,26}@[0-9.a-z]{0,20}.[0-9a-z]{0,8}", email) 45 print(m.group())\w+): (?P \S+)
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存