装饰器、迭代器、生成器、正则匹配


装饰器

个人对装饰器的理解如下:

 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()

装饰器就是用@格式添加在要执行函数体头部的一种语法,用于添加新功能。

迭代器&生成器

迭代器

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
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\w+): (?P\S+)', 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())

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存