软件定义园区网络的开发与实践-python高级学习笔记

1.介绍

  • 正则表达式
  • 装饰器
  • 迭代器
  • 生成器
  • 多任务

2.实践

2.1 正则表达式

用re模块检查一个字符串是否与某种模式匹配

  1. ^ 表示匹配字符串的开始位置 $ 表示匹配字符串的结束位置

  2.  匹配一个长度为0的子串

  3. s 匹配空白字符,比如空格,换行等

  4. 大小写快速取反

    • w 表示匹配英文字母和数字W 匹配非英文字母和数字
    • d 匹配数字 D 匹配非数字
  5. .表示匹配单个字符

  6. |表示为或者,两项中取一项 a|b 匹配a或者b

  7. ( ) 小括号表示匹配括号中全部字符 (abc) 匹配abc

  8. [] 中括号表示匹配括号中一个字符 [0-9 a-z A-Z]

  9. 重复匹配

    • {n}表示匹配n个字符
    • {n,}表示至少匹配n个字符
    • {n,m}表示至少n,最多m 优先匹配N个数字(贪婪模式)
    • {M,N}? 非贪婪模式,只匹配M个数字
    • *表示匹配0到多次
    • +表示匹配1次到多次
    • ? 表示匹配0或1
  10. 标记

    • re.I 使匹配不区分大小写
    • re.M (re.MULTILINE)多行匹配,影响 ^ 和 $
    • re.S (re.DOTALL)使 . 匹配包括换行在内的所有字符
    • re.U 根据Unicode字符集解析字符。这个标志影响 w, W

2.1.1 re.match

re.match 尝试从字符串的起始位置匹配一个模式

import re
print(re.match('www', 'www.huawei.com')) # 默认在起始位置匹配 www
print(re.match('com', 'www.huawei.com')) # 无法匹配
print(re.match('.*com$','www.huawei.com')) # 正则表达式表示匹配末尾为.com 的对象
<re.Match object; span=(0, 3), match='www'>
None
<re.Match object; span=(0, 14), match='www.huawei.com'>

2.1.2 re.search

扫描整个字符串并返回第一个成功的匹配

import re
print(re.search('www', 'www.huawei.com')) # 搜索到开始 www
print(re.search('com', 'www.huawei.com')) # 搜到到最末 com
print(re.search('.*com$','www.huawei.com')) # 正则表达式表示匹配末尾为.com 的对象
print(re.search('COM', 'www.huawei.com',re.I)) # 使大小写不敏感
<re.Match object; span=(0, 3), match='www'>
<re.Match object; span=(11, 14), match='com'>
<re.Match object; span=(0, 14), match='www.huawei.com'>
<re.Match object; span=(11, 14), match='com'>

2.1.3 re.sub

re.sub 用于替换字符串中的匹配项re.sub(pattern, repl, string, count=0, flags=0)

搜索pattern,替换成rep1

import re 
print(re.sub('^WWW','support', 'www.huawei.com',flags=re.I)) # 将开始的 www,替换为 support
support.huawei.com

2.1.4 re.compile

生成一个正则表达式(Pattern)对象,供 match() 和
search() 这两个函数使用

re.compile(pattern[, flags])

import re 
pattern = re.compile('d+') #匹配至少一个数字
print (pattern.match( 'www.huawei123.com')) #查看头部是否有数字,没有匹配
print (pattern.search( 'www.huawei123.com')) #搜索返回第一个数字
None
<re.Match object; span=(10, 13), match='123'>

2.1.5 findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹
配的,则返回空列表。

findall(string[, pos[, endpos]])

  • string 为待匹配字符串。
  • Pos 指定字符串的起始位置,默认为 0。
  • Endpos 指定字符串结束位置,默认为字符串长度
import re 
pattern = re.compile('d+') #匹配至少一个数字
print(pattern.findall( 'www.huawei123.com 
 345')) #查找所有字符串
['123', '345']

2.1.6 re.split()

split 按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

pattern 为正则表达式。string 为要匹配的字符串。Maxsplit 为分割次数,默认为 0 不限次数

import re 
s = re.split('W+', 'www.huawei.com') #W+表示匹配非英文和数字一次或多次
print(s)
['www', 'huawei', 'com']

2.2 装饰器

本质是一个 Python 函数,对函数的功能进行扩展,以@开头

#现有一个函数,输出 I am learning Decorators.
def test(): 
    print ("I am learning Decorators.") 
test()
I am learning Decorators.
#装饰器函数decorator()
def decorator(func): 
    def wrapper(): 
        print ("I learned Python Data Structures.") 
        func() 
    return wrapper 
@decorator 
def test(): 
    print ("I am learning Decorators.") 
test()
I learned Python Data Structures.
I am learning Decorators.

2.3 生成器

通过循环逐步获取集合后续的元素,yield 的函数被称为生成器(generator),可以降低内存占用

#使用圆括号编写生成器
G = ( x*2 for x in range(5)) #这里表示从 range(5)中每个 x*2 
print(type(G)) 
for i in G: 
    print (i)
<class 'generator'>
0
2
4
6
8

迭代器,是将一个集合的所有元素依次遍历。

而生成器返回的是一个迭代器,函数每次碰到 yield 关键词,就会把此关键字后面的值 添加进这个要返回的迭代器中,然后把生成器生成的这个 迭代器返回

# 使用 yield 关键字创建一个生成器
def fib(n): 
    current, num1, num2= 0, 0, 1 #初始化数值从 0,1 开始,current 为循环
    while True: 
        if current > n: #大于参数结束循环
            return 
        yield num1 #yield 将函数变为一个生成器,函数不断循环
        num1, num2 = num2, num1+num2 
        current += 1 
fib(5) 
for i in fib(5): 
    print (i)
0
1
1
2
3
5

唤醒生成器
可以使用 next 和 send 方法唤醒生成器,相比于 next 方法,send 在唤醒生成器时还可以向断点
处传入一个数据。

def gen(): 
    i = 0 
    while i<5: 
        temp = yield i 
        print(temp) 
        i+=1       
f = gen()
next(f)
f.send('haha') 
next(f) 
haha
None





2

2.4迭代器

可以记住遍历位置
的对象。迭代器从第一个元素开始访问,直到所有元素被访问完结束。

#使用 isinstance()方法判断对象是否是可迭代对象
from collections import Iterable # 可迭代对象
print(isinstance([], Iterable)) 
print(isinstance('abc', Iterable)) 
print(isinstance({'a':1,'b':2},Iterable)) 
print(isinstance(100, Iterable))
True
True
True
False


<ipython-input-10-a0aa53d20682>:2: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working
  from collections import Iterable # 可迭代对象
#通过 iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用 next()函数来获取下一条数据
l = [1, 2, 3, 4, 5] 
l_iter = iter(l) 
next(l_iter) 
next(l_iter) 
next(l_iter) 
3
#类里实现__iter__()和__next__()方法,可以实现一个迭代器。
#StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况
class Count: # 声明一个类实现迭代器
    def __iter__(self): # 实现__iter__方法
        self.a = 1 # 初始值为 1
        return self 
    def __next__(self): # 实现__next__方法,功能能为+1
        if self.a <= 5:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration # 迭代完成
mycount = Count()
myiter = iter(mycount)
for i in myiter: # 使用 for 循环遍历迭代器
    print (i)
1
2
3
4
5

2.5 多任务

多任务分为多线程和多进程。
线程通常位于进程
里面,由一个程序计数器、一个堆栈、一组寄存器和一个标识符组成

多线程:

线程同步,引入锁的概念,访问前锁定;

同步阻塞

#多线程可以用 threading 模块实现
import threading
from time import sleep,ctime # sleep 可以指定程序等待时间,ctime 可以返回本地时间
def work1(): # 定义函数 work1,间隔 1 秒输出 work1 字符串
    for i in range(3):
        print("work1 正在执行...%d"%i)
        sleep(1)
def work2(): # 定义函数 work2,间隔 1 秒输出 work2 字符串
    for i in range(3):
        print("work2 正在执行...%d"%i)
        sleep(1)
if __name__ == '__main__':
    print('---开始---:%s'%ctime())
    t1 = threading.Thread(target=work1) # 线程 1 调用 work1
    t2 = threading.Thread(target=work2) # 线程 2 调用 work2
                                        # 启动线程
    t1.start()
    t2.start()
     
    sleep(5)
print('---结束---:%s'%ctime())
---开始---:Mon Apr 26 19:48:10 2021
work1 正在执行...0
work2 正在执行...0
work1 正在执行...1work2 正在执行...1

work1 正在执行...2work2 正在执行...2

---结束---:Mon Apr 26 19:48:15 2021
#使用 Lock 可以实现简单的线程同步,这个对象有 acquire 方法和 release方法。
import threading
import time
g_num = 0 # 定义一个全局变量赋值为 0
def test1(num): # 定义函数 test1,对全局变量执行加操作
    global g_num # 使用全局变量
    for i in range(num):
        mutex.acquire() # 上锁
        g_num += 1
        mutex.release() # 解锁
    print("---test1--- g_num=%d" %g_num)
def test2(num): # 定义函数 test2,同样对全局变量加操作
    global g_num 
    for i in range(num):
        mutex.acquire() # 上锁
        g_num += 1 # 执行加操作
        mutex.release() # 解锁
    print("---test2--- g_num=%d" %g_num)
# 创建一个互斥锁
# 默认是未上锁的状态,可以删除锁后查看资源争夺的结果
mutex = threading.Lock()
# 创建 2 个线程,让他们各自对 g_num 加 1000000 次
p1 = threading.Thread(target=test1, args=(1000000,))
p1.start()
p2 = threading.Thread(target=test2, args=(1000000,))
p2.start()
# 等待计算完成
time.sleep(5)
print("2 个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
---test1--- g_num=1946509
---test2--- g_num=2000000
2 个线程对同一个全局变量操作之后的最终结果是:2000000

5.2 多进程

#coding=gbk #编码声明
from multiprocessing import Process 
import os 
import time 
 
nums = [11, 22] #设置全局的变量
 
def work1(): 
     """子进程 1 要执行的代码,对 nums 列表进行扩展""" 
    
    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums)) # 获取进程号
    for i in range(3): 
        nums.append(i) 
        time.sleep(1) 
        print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums)) 
 
def work2(): 
    """子进程 2 要执行的代码,输出进程号和调用 nums 列表""" 
    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums)) 
 
if __name__ == '__main__': 
    p1 = Process(target=work1) 
    p1.start()
    p1.join() #等此线程执行完后,再执行其他线程
 
     p2 = Process(target=work2)
     p2.start()

原文地址:https://www.cnblogs.com/zhuomoyixia/p/14706546.html