python基础语法总结笔记

目录

 

快捷键 

格式输出

变量类型

运算

循环与判断

if 条件语句

while循环语句

for遍历语句

序列操作

字符串 str

列表 list

元组 tuple

集合 set

字典 dict

推导式

生成器与迭代器

可迭代对象

迭代器

生成器

三者关系

函数与装饰器

函数定义

简化函数

递归函数

装饰器

常用函数

常用三方库

随机数

时间

日期时间

哈希加密

文件处理

TRY及异常处理

类 CLASS

类的定义与调用示例:

继承

封装

多态

模块

导入与自定义

进程与线程

进程

自定义进程

进程池

进程间的通讯,队列

线程

全局解释器锁GIL

死锁

生产者与消费者

协程

正则表达式

常用正则表达式:


快捷键 

快捷键作用
ctrl + 单击打开内置函数详情
ctrl + /将框选的代码注释/取消注释
tab将框选代码缩进一级
shift + tab 将框选代码取消缩进一级
ctrl + f 在目标处打开搜索栏
# 注释内容 单行语句注释
"""注释内容""" 多行语句注释

 

格式输出

普通输出

print(f'...{变量}...')
print('...%d...%f...%s...', % (整型变量,浮点变量,字符变量))
print('...{}...'.format(变量))

特殊输出

print('..."双引号内容"...\'单引号内容\'...')  #含引号数据的输出
print('...%.3f...%06d...', % (变量1,变量2)) #输出3位小数,6位整数(前面用0补齐)
print('...\n...\t...')                      #换行符,制表符Tab
print('...',end='结束符')                    #设置结束符,默认\n

 

变量类型

可变类型:列表、集合、字典

不可变类型:整型、浮点型、字符串、元组

type(数据)        #检测数据类型
int(数据)         #转换为整型
str(数据)         #转换为字符型
list(数据)        #转换为列表
set(数据)         #转换为集合
tuple(数据)       #转换为元组
chr(数据)         #ASCII转字符或Unicode转中文
ord(数据)         #字符转ASCII或中文转Unicode
eval(数据)        #字符串中有效数据自动转型
a,b=b,a           #变量值互换
id(变量)          #变量地址

 

运算

+                          #加
-                          #减
*                          #乘
/                          #除
//                         #整除
%                          #取余
**                         #指数
()                         #优先级
=                          #赋值
变量1,变量2=数据1,数据2    #多变量分别赋值
变量1,变量2=数据           #多变量赋相同值
c运算符=a                   #运算后赋值给c,例如c%=a等价于c=c%a
==                         #判断相等
!=                         #判断不等
>与<                       #大于与小于
>=与<=                     #大于等于与小于等于
and                        #与运算
or                         #或运算
not                        #非运算

 

循环与判断

if 条件语句

格式:

if条件1:
    条件1成立时的任务
elif条件2:
    条件2成立时的任务
else:
    所有条件均不满足时的任务

 

三目运算:

c = 返回值1 if 条件 else 返回值2          #若条件成立赋值1,否则赋值2

例如:

c = a if a>b else b       # c等于a和b中较大者

 

while循环语句

格式:

while 条件1:         #当满足条件1时,执行循环
    任务1
    if 条件2:        #当满足条件2时,跳出此层循环
        任务2
        break
    if 条件3:        #当满足条件3时,结束此次循环,直接进入下一次循环
        任务3
        continue
    if 条件4:        #当满足条件4时,跳出所有循环,结束进程
        任务4
        return
    任务5            #上述条件均不成立时执行此任务
else:
    任务6            #循环正常完成后的任务,若循环不开始或者跳出,则不执行
任务7                #循环外的任务

注意:

    如果是限次循环,需要重复n次,初始值为c,则条件是<n+c

    一般在循环最后进行 i+=1 的操作,注意continue所对应的任务中需要单独进行 i+=1 的操作

 

while语法常常用于需要持续执行任务,或者需要等待触发等情况

如果while中还有内部循环,可通过break跳出当前层循环,或者return跳出所有循环结束进程

while True:
    任务1
    if 触发条件:
        任务2
        break
    任务3
    for i in range(100):
        任务4
        if 跳出此层循环条件:
            任务5
            break
        if 跳出所有循环条件:
            任务6
            continue
    任务7

 

for遍历语句

格式:

for 临时变量 in 序列:
    任务1
    if 条件2:        #当满足条件2时,跳出此层循环
        任务2
        break
    if 条件3:        #当满足条件3时,结束此次循环,直接进入下一次循环
        任务3
        continue
    if 条件4:        #当满足条件4时,跳出所有循环,结束进程
        任务4
        return
    任务5            #上述条件均不成立时执行此任务
else:
    任务6            #循环正常完成后的任务,若循环不开始或者跳出,则不执行
任务7

 

序列操作

字符串 str

格式作用
str[i]索引第 i 位字符
str[m,n,b]

索引 [m,n) 范围内按步长b切片

若m、n为负数表示反向索引,倒数第m位

若b为负数表示反向切割

 
str.split(子串或字符, 次数)

切割掉子串或字符,剩余部分以列表返回

 
str.replace(旧子串, 新子串, 次数)

将旧子串替换为新子串

当新子串为空时,可作为删除子串使用

 

 
str.remove(子串)

移除首个指定子串

 
str.clear()

清空字符串变量

 
str.append(子串)末尾添加子串 
str.insert(索引, 子串)在索引处插入子串 
str.find(目标子串, m, n)

索引 [m,n) 范围内查找子串首次出现的索引

rfind表示从右往左查找

若未找到返回-1

 
str.index(目标子串, m, n)

索引 [m,n) 范围内查找子串首次出现的索引

rindex表示从右往左查找

若未找到报错

 
str.count(目标子串, m, n)统计 [m,n) 范围内子串出现的次数 
str.strip()

两侧删除空白字符

rstrip()删除右侧空白

lstrip()删除左侧空白

 
str.capitalize()字符串首字符大写 
str.title()字符串中所有单词首字母大写 
str.upper()

所有小写转大写

lower()所有大写转小写

 
str.ljust(数据长度, '填充内容')

数据长度内左对齐,不足时自动填充

rjust(数据长度, '填充内容')右对齐

center(数据长度, '填充内容')居中对齐

 
str.startswith(子串, m, n)

判断 [m,n) 范围内是否以子串开始

endswith(子串, m, n)判断结束

 
str.isalpha()

判断是否全部由字符构成

isdigit()判断是否全部由数字构成

isalnum()判断是否全部由数字、字符构成

isspace()判断是否全部由空格构成

 
子串 in str

判断是否含有子串

not in判断不含子串

 
'起始字串'.join(字串列表)将列表中的所有字串合并成一个字符串 
str.reverse()将字符串逆序 
str.copy()复制,str变化,则变量同时变化 
len(str)字符串长度 
str1 + str2合并两个字符串

 

列表 list

常用的批量存储

格式:[数据1, 数据2, ..., 数据n]

 

元组 tuple

元组数据不能修改

格式:(数据1, 数据2, ..., 数据n)

格式作用
tuple()创建空元组
tuple.index(i)索引第 i 位元素
tuple.count(元素)元素出现次数
len(tuple)元组容量
tuple1 + tuple2元组合并

 

集合 set

无重复数据存储,常用于去重

格式:{数据1, 数据2, ..., 数据n}

格式作用
set()创建空集合
set.add(数据)添加元素
set.update(list)添加数据序列
set.remove(数据)删除元素
set.discard(数据)删除元素
set.pop()随机删除元素,并返回该元素

 

字典 dict

以键值对的形式对应存储数据

格式:{'key1': 数据1, 'key2': 数据2, ... ..., 'key': 数据}

格式作用
dict{}创建空字典
dict[key] = 数据更改数据/添加键值对
dict[key].del()删除键值对
dict.clear()清空字典
dict.get(key, 返回值)按key查找,若未找到返回设定值,默认为None
dict.keys()获取key列表
dict.values()获取数据列表
dict.items()拆包字典,返回 [(key1, 数据1), (key2, 数据2), ...]

 

推导式

list = [i for i in range(10)]
list = [i for i in range(10) if i % 2 == 0]        #附带条件
list = [(i,j) for i in range(3) for j in range(3)] #for循环嵌套,返回元组(i,j)
dict = {key : i**2 for i in range(5)}
dict = {list1[i] : list2[i] for i in range(len(list1))}  #双列表构成字典
dict = {key : value for key,value in dict.items() if value >= 200}  #字典过滤

 

生成器与迭代器

可迭代对象

生成器gen、迭代器iter、列表list、元组tuple、字符串str、集合set、字典dict

判断是否可迭代:

from collections import Iterable
isinstance(对象, Iterable)

 

迭代器

可以被next()调用并返回下一个值的对象,称为迭代器iteration

iter(可迭代对象)    #将可迭代对象转化为迭代器

 

生成器

近似等同于推导式,但节省内存,即用即推

g=推导式
g.__next()__    # 通过调用生产元素,每次调用生产一个,顺序向下
next(g)         # 同上

def func:
    ...
    yield g     # 定义g为生成器,等效于"returng并暂停保存g"

g.send(值)      # 向生成器传值,初次传入None

 

通过下面的代码加深理解

"""
费莫纳契数列【1,1,2,3,5,8,13。。。】
"""
def Femonacci(length):    # 费莫纳契数列元素生成器
    a,b=0,1
    n=0
    while n < length:
        yield b
        a,b=b,a+b
        n+=1
        return 'no rest'

byte = 8                  #数列长度
Fmnc_list = []
g = Femonacci(byte)
for i in range(byte):     #循环调用生成器,自动生成指定长度的数列
    element = next(g)
    print(element,end='')
    Fmnc_list.append(element)
print('\n',Fmnc_list)

#...............................................................................

"""
利用生成器进行多协程工作,让多种工作交替执行,或分组执行
"""
def task1(j):
    for i in range(j):
        print(f'正在搬第{i}块砖')
        yield None

def task2(j):
    for i in range(j):
        print(f'听第{i}首歌')
        yield None

n = 5
g1 = task1(n)
g2 = task2(n)
while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        pass

 

三者关系

生成器 ∈ 迭代器 ∈ 可迭代对象 

除迭代器外,可迭代对象还包括 列表、元组、集合、字典、字符串

 

函数与装饰器

函数定义

def func(参数):                #定义函数
"""说明文档"""
    任务
    return 返回值

help(func)                     #查看函数说明文档
global 变量                    #函数内声明全局变量,函数有权修改变量值

def func(参数1,参数2):          #多变量函数定义
    pass
func(数据1,数据2)               #函数调用,位置传参
func(参数1=数据1,参数2=数据2)    #函数调用,关键词传参

def func(参数1,参数2=默认值):    #定义带默认参数值的函数
    pass
func(数据1)                     #缺省默认参数
func(数据1,数据2):              #默认参数修改

def func(*args,**kwargs):      #设置可变参数和可变关键字参数,任意格式参数
    pass

 

简化函数

以map、lambda、filter、reduce、sorted为例

"""
利用lambda匿名函数进行偶数判断
用map自动将list1中的元素进行函数处理
"""

list1 = [1,2,4,6,4,6,3,8,6,4,6,3,9]
result1 = map(lambdax : x if x % 2 == 0 else x + 1, list1)#嵌套函数简化
print(list(result1))#结果转换为列表格式输出

"""
利用lambda匿名函数进行求和
用reduce自动将tuple中的元素进行函数处理
"""

from functools import reduce
tuple1 = (3, 5, 7, 8, 9, 1)
result2 = reduce(lambda x, y : x + y, tuple1, 10)
#初始值为10,对元组tuple1内所有元素,进行加法处理
print(result2)

"""
利用lambda匿名函数进行判断大于10
用filter自动将list2中符合体条件的元素存入新列表
注意:filter不改变原列表
"""

list2 = [12,6,8,98,34,36,67,3,0]
result3 = filter(lambda x : x > 10, list2)  #对list2中所有元素筛选出大于10的元素
print(list(result3))     #将结果转换为列表格式

"""
利用lambda匿名函数调取字典中的age数据
用sorted自动将字典中的元素(列表)排序
"""

dict1 = [{'name': 'Tom', 'age': 24}, {'name': 'Lily', 'age': 17},{'name': 'Jerry', 'age': 20},{'name': 'Golf', 'age': 7}]
result4 = sorted(dict1, key=lambda x : x['age'], reverse=False)
#对字典中age数据进行正序排列
print(result4)

 

递归函数

"""
利用递归调用的方法,求10——0的和
递归函数:1)有始有终
         2)自己调用自己
"""

def func1(n):
    if n==0:
        return0
    else:
        return n + func1(n-1)
print(func1(10))

递归函数条件:

    自己调用自己、加判断作为终点(出口)、有初值(入口)

 

装饰器

主要用于触发强制执行,例如页面需要登录才能进一步访问

def func1:
    def func2:
        pass
        return func2

@func1:
def func3:
    pass

func3

工作原理:顺序定义   调用func3   找到func3所在装饰器func1   找到func1   执行func1下属的所有函数和代码(包括func2)

而对于以下代码

@decorate1
def func:
    pass

@decorate2
def func:
    pass

func

多次装饰器,采用就近优先的原则,执行decorate2

装饰器sh:登录付款系统

"""
登陆状态判断,以及强行跳转,采用装饰器
需要强行跳转的函数,在其定义前使用装饰器@函数名
此处是在付款函数的定义前加登陆验证判断
装饰器是将函数作为参数,传入装饰器函数中,相当于调用被装饰函数=调用装饰器内部所定义的函数
"""

import time              #导入时间库

islogin = False          #登陆状态,默认未登陆

#登陆界面
def login():
    username = input('输入用户名:')
    password = input('输入密码:')
    if username == 'admin' and password == '123456': 
    #用户名、密码核对正确,更改登录状态为True
        return True
    else:
        return False

#验证付款登陆(装饰器)
def login_required(func):
    def wrapper(*args,**kwargs):    #wrapper的参数格式可变
        global islogin              #后面会更改全局变量islogin的值,需要声明
        print('------------付款---------------')
       
        #验证登陆
        if islogin:        #若登陆成功,执行func,即执行pay
            func(*args,**kwargs)
        else:            #若未登陆,进入login
            print('用户未登陆,不能付款')
            islogin=login()
            print('result:',islogin)
    return    wrapper#表示func=wrapper,即pay=wrapper

#验证付款
@login_required        #调用付款函数前需要验证,类似于login_required(pay)
def pay(money):
    print(f'正在付款,付款金额为:{money}')
    print('付款中。。。')
    time.sleep(2)#延时2s
    print('付款完成')

#付款操作
while True:
    pay(input('输入付款金额'))#只有登录状态,才能执行付款

 

常用函数

range(数字)          #[0,n)中整数列表
reage(m, n, b)      #[m,n)中整数列表,步长为b
input('输入提示')    #输入
del()               #删除变量
pop()               #删除变量,返回数据
max()               #获取最大值
min()               #获取最小值

 

常用三方库

名字作用
builtins内建函数,默认加载
math数学库
random生成随机数

time

时间
datetime日期、时间
calendar日历
hashlib加密算法
copy拷贝
functools常用工具
os操作系统接口
re字符串正则
syspython自身的运行环境
multiprocessing多进程
threading多线程
json编码和解码 json对象
login记录日志、调试

随机数

import random
random.random()            #随机地址
random.randrange(1,10,2)   #产生整型随机数,从1到10,步长2
random.randint(1,10)       #产生整型随机数
list1 = ['red', 'yellow', 'blue', 'green', 'black']
random.choice(list1)       #随机列表内元素
random.shuffle(list1)      #洗牌动作,打乱列表
print(list1)

例如,生成随机验证码:

#验证码生成,包含大写字母和数字
def func():
    code=''
    for i in range(4):
        ran1 = str(random.randint(0,9))     #随机数字
        ran2 = chr(random.randint(65,90))   #随机大写字母(对应ASCII码)
        ran3 = chr(random.randint(97,122))  #随机小写字母
        r = random.choice([ran1,ran2,ran3]) #随机选择数字、大小写字母
        code += r                           #组成四位随机字符串
    return code

code1 = func()
print(code1)

 

时间

import time
time.sleep(n)            #延时n秒
t=time.time()            #时间戳,当前时间数值,单位秒,浮点型
print(t)
print(time.ctime())      #当前时间,字符串
print(time.localtime().tm_mon)    #当前时间,元组(当前取出月份)
print(time.strftime('%Y-%m-%d%H:%M:%S'))    #自定义格式时间,对应格式见函数内(Ctrl+点击)

 

日期时间

import datetime
print(datetime.date.today())    #当前日期
pretime = datetime.datetime.now() - datetime.timedelta(hours=2) #两个小时前的时间
print(pretime)

 

哈希加密

#单向(md5、sha1、sha256)
#可加可解(base64)
import hashlib                     #哈希加密库
msg1 = '加密文件'
msg_code = msg1.encode('utf-8')    #信息编码
msg_md5 = hashlib.md5(msg_code)    #对编码后的信息进行md5加密
print(msg_md5.hexdigest())         #以16进制表示加密后的信息
msg_sha1 = hashlib.sha1(msg_code)  #对编码后的信息进行sha1加密
print(msg_sha1.hexdigest())
msg_sha256 = hashlib.sha256(msg_code)  #对编码后的信息进行sha256加密
print(msg_sha256.hexdigest())

加密应用项目:

#密码加密举例
password = '123456'        #设置密码
list2 = []
password_sha256 = hashlib.sha256(password.encode('utf-8'))  #对密码进行编码、sha256加密
list2.append(password_sha256.hexdigest())                   #将加密后的密码添加至密码列表中
pwd = input('输入密码:')                                    #用户输入
pwd_sha256 = hashlib.sha256(pwd.encode('utf-8'))            #对输入信息进行编码、sha256加密
pwd=password_sha256.hexdigest()                             #将加密后的用户输入,用16进制表示
print(pwd)
for i in list2:      #遍历密码列表,若加密后的用户输入和密码列表能对应,则登陆成功
    if pwd == i:
        print('登陆成功')

 

文件处理

python进行文件的读取写入操作需要借助数据流,相当于创建一个中间级,将数据以暂存的方式传输

with open('文件路径',mode='mode') as stream:
    文件操作

文件操作

文件路径包括 绝对路径和相对路径

    绝对路径:从硬盘开始,到文件名

    相对路径:同级直接写文件名,上级加 ../ ,下级加 /

模式mode包括:

    r        纯文本文件读取

    w      纯文本文件写入,会清空原有记录

    rb     二进制读取,支持文本、图片、音乐、视频等

    wb    二进制写入,支持文本、图片、音乐、视频等,会清空原有记录

    a       添加,不清空原有记录

    x       新建,文件已存在会报错

文件操作包括:

#读操作
open(path/filename,'r')    #创建读取流,返回stream(流)
stream.read()              #读取信息
stream.readable()          #是否可读
stream.readline()          #读取一行
stream.readlines()         #按行读取,返回列表

#写操作
open(path/filename,'w')    #创建写入流,返回stream(流)
stream.write()             #写入信息
stream.writeline()         #写入行
stream.writelines([])      #依次写入列表中的元素

#添操作
open(path/filename,'a')    #创建添加流,返回stream(流)
stream.write()             #写入信息
stream.writelines([])      #依次写入列表中的元素

#新建操作
open(path/filename,'x')    #创建新建&写入流,若已存在会报错

#关闭流,释放内存
stream.close()

文件复制:

# 单个文件复制
with open('文件路径','rb') as stream1:
    变量 = stream1.read()
with open('新文件路径','wb') as stream2:
    stream.write(变量)

#文件夹下所有文件复制
import os#导入os库
def copyfiles(src,target)                        #(封装函数)
    if os.path.isdir(src) and os.path.isdir(target):
    #判断src和target是否为有效路径
        filelist = os.listdir(src)
        for file in filelist:                    #遍历src路径下所有文件
            path = os.path.join(src,file)        #将文件夹和文件名组合成绝对路径
            with open(path,'rb') as stream1:     #复制操作,将所有文件复制至target路径
                container = stream1.read()
            path1 = os.path.join(target,file)
            with open(target,'wb') as stream2:
                stream2.write(container)
    else:                                        #结束复制
        print('复制完毕')

文件路径相关

stream.name()        #流所对应的路径
file.rfind('str')    #文件路径(字符串)从右开始,str首次出现的位置
file.lfind('str')    #文件路径(字符串)从左开始,str首次出现的位置
file[file.rfind('\\')+1:]    #file文件名

import os            #os模块(operatesystem操作系统,往往与路径相关)
os.path.join(path,'str')     #将已有路径后加上str部分
os.path.isabs(path)          #判断是否是绝对路径
os.path.isdir(path)          #判断是否是文件夹
os.path.dirname(__file__)    #当前文件所在文件夹的路径
os.path.abspath(path)        #相对路径转换为绝对路径
os.path.split(path)          #得到元组(文件夹路径,文件名)切割出文件名
os.path.splitext(path)       #得到元组(文件路径,文件类型)切割出文件扩展名
os.path.getsize(path)        #获取文件大小,单位字节
os.path.exists(path)         #判断文件是否存在

os.getcwd()                  #当前文件所在文件夹的路径
os.listdir(path)             #返回目录中所有文件和文件夹名字列表
os.mkdir(path)               #路径下创建文件夹(已有文件会报错)
os.rmdir(path)               #移除文件(只能删除空文件夹)
os.removedirs(path)          #移除目录下空文件
os.remove(path)              #删除文件
os.chdir(path)               #将当前文件路径更换至指定路径(进入指定目录)

文件操作小项目1:

需要创建对应的 user.txt

"""
注册登录系统:
用户登录,在用户信息储存文件中核对用户名和密码,判断是否正确
用户注册,成功注册后会将新用户信息写入用户信息储存文件
"""

def register():
    username = input('输入用户名:')
    password = input('输入密码:')
    repassword = input('再次输入密码')
    if password == repassword:
        with open(r'C:\path\user.txt','a') as wstream:
            wstream.write('{}{}\n'.format(username,password))
            print('注册成功')
            login()
    else:
        print('注册失败,请重新注册')
        return register()

def login():
    username = input('请输入用户名')
    password = input('请输入密码')
    input_info = '{}{}\n'.format(username,password)
    if username and password:
        with open(r'C:\new_path\user.txt','r') as rstream:
        user_infos = rstream.readlines()
        if input_info in user_infos:
            print('登录成功')
        else:
            print('用户名或密码错误')
            choise = input('1、重新登录2、注册')
            if choise == '2':
                register()
            else:
                return login()

login()

文件操作小项目2:

复制文件夹内所有内容,包括图片、文本、内部文件夹

import os

def cpfiles(src_path,target_path):
    filelist = os.listdir(src_path)         #获取文件夹内的文件,得到文件列表
    for file in filelist:                   #遍历文件列表
        path=os.path.join(src_path,file)    #拼接路劲
        if os.path.isdir(path):             #判断是否为文件夹
            nfile_path = os.path.join(target_path,file)    #拼接路径
            os.mkdir(nfile_path)            #创建新文件夹
            cpfiles(path,nfile_path)        #对文件夹内容,递归
        else:                               #不是文件夹,复制
            with open(path,'rb') as rstream:    #创建读取流
                container = rstream.read()      #读取内容
                target_file = os.path.join(target_path,file)    #拼接路径
            with open(target_file,'wb') as wstream:             #创建写入流
                wstream.write(container)    #粘贴内容
    else:                                   #遍历完成,复制完成
        print('复制完成')

cpfiles(r'C:\path\file_test', r'C:\path\copy_test')

 

TRY及异常处理

try用于进行代码尝试,针对可能报错的代码,进行尝试执行,如果报错,进行预设处理,不会让代码停下,而是继续执行

try:
    可能出现异常的代码
    return 1

except error1 as err:    #异常1时获取异常说明err
    异常1时执行的代码
    print(err)

except error2:
    异常2时执行的代码
    return 2

else:
    无异常时执行的代码

finally:
    无论是否异常都会执行的代码
    return 3             #会覆盖前值,返回3

代码报错会优先父辈,为了便于排查错误,对于except对应的错误,按辈分从低到高顺序排列,最泛泛的error放在最后

 

自定义函数时,可通过自定义异常条件及异常说明,便于调用时进行错误提示和进行try操作

def register():
    username = input('输入用户名:')
    if len(username) < 6:
        raise Exception('用户名长度必须6位以上')    #抛出异常与异常说明
    else:
        print('输入的用户名是:',username)

try:
    register()

except Exception as err:               #运行异常,获取异常说明
    print(err)
    print('注册失败')

else:
    print('注册成功')

 

类 CLASS

类: 将具有公共属性及方法的变量定义为类

类属性: 类自身固有的性质、变量及默认值,以及不可修改值

对象属性:定义在类中的属性,每个对象拥有不同属性值

类方法: 定义在类中的函数,参数为cls,调用时用 对象.方法,可用于修改不可修改类属性

@classmethod
def 方法名(cls,[参数]):
    内容

类名.方法名()
对象.方法名()

对象方法:定义在类中的函数,参数为self,调用时用 对象.方法(变量值),不可调用类方法,不改变类属性默认值

魔术方法:触发自动执行

                    init 动态定义所有属性变量,并用传入的值赋于变量,

                    new 优先执行,开辟一块内存存储类,返回值作为self

                    call 让对象可作为函数调用,内容为call下代码

                    del 删除相同对象的引用(一般不用)

                    str 调用对象可以给出对象信息

静态方法: 无需传参,只能访问类方法和类属性,无法访问对象

@staticmethod
def 方法名():
    内容

类名.方法名()
对象.方法名()

类之间关系(继承): is a 与 has a​

 

类的定义与调用示例:

class Cat:                #定义类
    type='猫'             #定义类属性及默认值
    name='小猫'
    __sex='man'           #定义类属性不可更改,类外无法直接修改

    def __init__(self,name,age):    #定义初始化魔术方法,以及动态属性变量(属于对象方法)
        print('---------->init')
        self.age = age    #将传入的变量值赋给对象属性
                         ##注意:此时name没有赋值,沿用默认值

    def __new__(cls,*args,**kwargs):   #优先执行,新开辟一块内存,返回值作为self
        print('---------->new')
        return object.__new__(cls)     #返回内存位置,并作为self

    def __call__(self,parameter):      #调用执行,将对象类似于函数调用
        print('---------->call')
        print('外界传入的name为{}'.format(parameter))

    def __del__(self):                 #对象无引用时,执行
        print('---------->del')       ##注意:此方法容易覆盖python默认回收机制,一般不使用

    def __str__(self):                 #对象的信息(不再是地址)
        print('---------->str')
        return '名字叫' + self.name+',年龄为' + str(self.age)

    def eat(self,food):                #定义对象方法及变量
        print('{}正在吃{}'.format(self.name,food))

    def run(self):
        print('{}今年{}岁,正在玩耍'.format(self.name,self.age))

@classmethod
def test1(cls):                        #定义类方法(只能访问类属性、类方法)
    print('------->类方法')
    print(cls.name,cls.__sex)          #打印类属性

@classmethod
def sex_change(cls):    #定义类方法(用于修改类属性)
    __sex='wuman'       #修改类属性
    print(cls.__sex)
    return__sex         #调用时返回修改后的类属性

@staticmethod
def test2():            #定义静态方法
    print('------->静态方法')
    print(Cat.__sex,Cat.name)    #打印类属性

p1 = Cat('lisi',20)           #调用类,创建对象,赋值变量,执行new
print(dir(Cat))               #类的方法、属性
print(dir(p1))                #对象方法、属性
p1.run()                      #调用类对象方法,使用赋值参数
p1.name = '咪咪'              #覆盖属性默认值
p1.eat('老鼠')                #调用类对象方法,并传递变量参数
p1.test1()                    #调用类方法
print(p1.sex_change())        #修改类属性sex
p1.test2()                    #调用静态方法
p1('inputparameter')          #调用call()
print(p1)

importsys                     #导入sys库
p2 = p1                       #增加对象引用
print(sys.getrefcount(p1))    #获取p1调用次数(包括当前操作)
delp2                         #删除p2引用,获取此时p1调用次数
print(sys.getrefcount(p1))
delp1                         #当引用全部删除(次数==1)则执行del内容

 

继承

类属性或方法的共有

class Person:                   #定义类:人
    def __init__(self,name):    #定义对象初始属性(人共有)
        self.name = name
        self.age = 18
    
def eat(self):                  #定义方法(人共有)
        print(self.name+'正在吃饭')

class Student(Person):          #定义类:学生,继承父类Person
    def __init__(self,name,major):    #定义对象初始属性
        super().__init__(name)        #子类定义init时必须包括定义父辈init
        self.major=major              #Student独有属性
        print('--------->Student的init')

    def study(self,course):           #定义方法
        print('{}正在学习{}课程'.format(self.name,course))

stu = Student('Jack','computer')      #创建对象
stu.eat()                             #执行方法,方法来自Person继承
stu.study('python基础')

在继承关系中,往往有 广度优先和深度优先 两大类

当存在多级继承的情况时,python采用广度优先的新式类

"""
多继承的优先级顺序问题
python3采用新式类:广度优先
"""

class P1:
    def foo(self):
        print('------->P1_foo')

    def bar(self):
        print('------->p1_bar')

class P2:
    def foo(self):
        print('------->p2_foo')

class C1(P1,P2):
    pass

class C2(P1,P2):
    def bar(self):
        print('------->c2_bar')

class D(C1,C2):
    pass

print(D.__mro__)    #查看搜索顺序
d=D()
d.foo()
d.bar()

 

封装

类属性的私有化,类外无访问权限

"""
封装:将某些属性私有化,类外无法访问
通过装饰器来授予权限
"""

class Student:
    def __init__(self,age):
        self.__age=age        #属性私有,外界无权访问

    @property                 #允许外界取出属性
    def age(self):
        return self.__age

    @age.setter               #为age加装饰器,防止同名方法就近调用
    def age(self,age):        #允许外界修改属性
        self.__age = age

s = Student(50)
print(s.age)
s.age = 10
print(s.age)

 

多态

类下共有

属于同一个类的不同对象,可以拥有自身独有的属性

"""
多态:通过加判断来限制动作对象,只有子类才能执行方法,否则不能执行
"""

class Person:
    def __init__(self,name):
        self.name = name

    def feed_pet(self,pet):         #接受传参
        if isinstance(pet,Pet):     #判断是否是子类
            print('{}喜欢养宠物:{},昵称是{}'.format(self.name,pet.role,pet.nickname))
        else:
            print('不是宠物,不能养')

class Pet:
    role = '宠物'
    def __init__(self,nickname,age):
        self.nickname = nickname
        self.age = age

    def show(self):
        print('昵称:{},年龄:{}'.format(self.nickname,self.age))

class Cat(Pet):                     #定义宠物子类,猫
    role = '猫'
    def catch_mouse(self):
        print('抓老鼠。。。')

class Dog(Pet):                     #定义宠物子类,狗
    role = '狗'
    def watch_house(self):
        print('看门。。。')

class Tigger:                       #定义无关类,老虎
    role = '大老虎'
    def eat(self):
        print('太可怕了,能吃人')

cat = Cat('花花',2)                 #创建各类对象
dog = Dog('大黄',4)
tigger = Tigger()
person = Person('张伟')
person.feed_pet(cat)                #子类执行方法
person.feed_pet(tigger)             #非子类执行方法

 

模块

导入与自定义

模块就是具有一定功能的py文件

包就是存储纯py文件的文件夹,必须包括 __init__.py 和 各模块.py

导入模块:

        1.import 模块名

                 模块名.变量/函数/类

        2.from 模块名 import 变量/函数/类, ....

                 在代码中可以直接使用变量,函数,类

        3.from 模块名 import *

                 导入该模块中所有的内容 但是如果想限制获取的内容,可以在自定义模块中使用__all__=[*允许访问的内容, ...]

        4.无论是import还是from的形式,都会将模块内的所有内容加载

         如果不希望其进行内部语句调用,可在自定义模块中加入:

                 def test():...                      /定义模块中的函数

                 func                                 /导入模块必定执行

                 if func == '__main__':       /当且仅当本py文件运行时执行test函数,若本py文件被调用执行,则不执行test函数

         test() 在自己的模块里面__name__叫:__main__

         在其他模块中通过导入的方式调用时,__name__叫;__模块名__​

 

__init__.py文件:

当导入包的时候,默认调用__init__.py文件

作用:

        1.当导入包的时候,把一些初始化的函数,变量,类定义在__init__.py文件中

        2.此文件中函数,变量等的访问,只需要通过包名.函数. ...

        3.结合__all__=[通过*可以访问的模块]​

 

循环导入的情况:
    模块A: 
        from B import funcB 
        def funcA: 
    模块B: 
        from A import funcA 
        def funcB: 
模块之间相互导入,发生错误 
解决方法: 
1.重新架构 
2.将导入的语句放入函数里面 
3.将导入语句放到模块的最后

 

进程与线程

并发:将独立CPU运行时间拆分为若干个时间段,并将他们分配给各线程执行 
并行:每一个CPU执行一个线程,两个线程互不抢占CPU资源,可以同时进行 
进程:程序对于某数据集合的一次运行活动,稳定性高(一个进程崩溃,不影响其他进程)无先后执行顺序,以同时进行为目的 
线程: 

进程与线程:进程是分配空间,线程是分配时间 
                    cpu包括多进程,进程包括多线程 
                    进程往往完成计算密集型操作 
                    线程往往完成耗时较长的任务,避免长期占用内存 
                    协程适用于耗时操作,例如网络请求、IO操作,协程的目的在于高效利用CPU 
实现多任务的方式: 
    1、多进程模式:平行进程争夺CPU空间 
    2、多线程模式:平行线程争夺进程所有空间 
    3、协程:微线程 
进程 》线程 》协程

 

进程

from multiprocessing import Process

Process(target= 函数, name= 进程的名字, args= 给函数传递的参数)

process.start()                    启动进程

process.run()                      执行任务但不启动进程

process.terminate()            终止​

#进程
#linux系统采用folk创建进程
#windows系统采用multiprocessing创建进程

import os
from multiprocessing import Process
from time import sleep

sleep_num = 0        #声明全局变量,观察结果(全局变量在平行进程中相互独立,互不影响,不共用)

                                       #(全局变量在平行线程中共用,都可对变量进行调用处理)
def task1():
    global sleep_num
    while True:
        sleep(1)
        sleep_num += 1
        print('这是子进程1',os.getpid(),'这是主进程',os.getppid(),'进程1沉睡次数=',sleep_num)

def task2(second,name):
    global sleep_num
    while True:
        sleep(second)
        sleep_num += 1
        print('这是子进程2',os.getpid(),'这是主进程',os.getppid(),'进程2沉睡次数=',sleep_num,name)

def task3(second):
    while True:
        print(f'thisisprocess3,pleasewaitingfor{second}s')
        sleep(second)
        print('这是进程3')

if __name__ == '__main__':        #主进程开始
    print('---------start----------')
    print(os.getppid())        #打印主进程pid
    p1 = Process(target=task1,name='任务1')
    #创建任务1为进程,task加()表示返回值,不加括号表示函数本身,此处不能加()
    p1.start()                 #启动进程

    p2 = Process(target=task2,name='任务2',args=(2,'名字是任务2')) 
    #进程传参:args=元组或列表
    p2.start()

    p3 = Process(target=task3,name='任务3',args=(3,))
    p3.start()

    print(p1.name)              #打印进程1的名字
    number = 0
    while True:
        number += 1
        sleep(0.1)
        if number == 30:        #结束进程
            p1.terminate()
            p2.terminate()
            print('进程1、2结束')
        elif number == 70:
            p3.terminate()
            break
        else:
            print('number=',number)    #用于观察进程运行状况

 

自定义进程

将进程定义为类

"""
自定义进程:
通过创建类,自定义进程的参数、内容等
通过类,创建具有相同功能的进程
"""

from multiprocessing import Process
from time import sleep

class MyProcess(Process):     #把自定义进程,定义为一个类
    def __init__(self,name):  #通过__init__添加参数name
        super(MyProcess,self).__init__()
        self.name = name

    def run(self):            #进程运行的内容,打印并延时0.5s
        n=1
        while True:
            print('自定义进程名字为{},n={}'.format(self.name,n))
            n+=1
            sleep(0.5)

i=0
if __name__ == '__main__':#主程序(主进程)
    p1 = MyProcess('进程1')    #按自定义进程类,创建进程
    p2 = MyProcess('进程2')
    p1.start()                 #启动进程
    p2.start()
    while True:
    if i == 3:                 #当3s后结束进程
        p1.terminate()
        p2.terminate()
        break
    sleep(1)                   #按秒判断
    i+=1

 

进程池

"""
进程池Pool
用于创建大量进程,初始化Pool时,指定一个最大进程数,当新的请求提交到Pool时,若池未满,自动创建新进程用来执行该请求;若池已满,则该请求等待直到池中有进程结束,则创建新进程

阻塞式:添加一个任务执行一个,任务不结束,下一个任务无法进入,当有任务结束时,接下来的任务会接替该任务的id执行,直至全部进程执行完毕

非阻塞式:进程全部添加到队列中,立刻返回,并没有等待其他的进程执行完毕,但是回调函数是等待所有任务全部完成之后才会执行,当有任务结束时,接下来的任务会接替该任务的id执行,直至全部进程执行完毕
"""

from multiprocessing import Pool
from random import random
import time
import os

container = []

def task(task_name):
    print('开始做任务了',task_name)
    start = time.time()
    time.sleep(random()*2)
    end = time.time()
    print('完成任务',task_name,'进程执行用时:',(end-start),'pid:',os.getpid())
    return'完成任务:{},用时:{},进程id:{}'.format(task_name,(end-start),os.getpid())

def callback_func(n):
    container.append(n)

if __name__ == '__main__':        #快捷键main+enter键
    pool  =Pool(5)                #设置进程池容量
    task_list = ['听音乐','吃饭','打游戏','写作业','学python','睡觉','聊天']
    for i in task_list:
    #pool.apply(task,args=(i,))   #阻塞式:任务、参数
    pool.apply_async(task,args=(i,),callback=callback_func) #非阻塞式:任务、参数、回调函数
    pool.close()                  #申请添加任务结束
    pool.join()         #主进程让步,优先pool,只有当进程池中子进程全部结束,才会结束主进程
    print(container)    #阻塞式无回调,非阻塞可以回调

 

进程间的通讯,队列

"""
进程间的通信:队列queue

q.put()    如果queue满了则只能等待,除非有空位则添加成功
q.full()   判断是否满
q.empty()  判断是否空
q.qsize()  队列空间大小
q.close()  关闭队列
q.get()    获取队列中的任务
"""

from multiprocessing import Queue
from multiprocessing import Process
import time 

def download(queue):
    images = ['flower.jpg','grass.jpg','sun.jpg','house.jpg','kid.jpg']
    for i in images:
        print('正在下载:',i)
        time.sleep(0.5)
        queue.put(i)

def getfile(queue):
    while True:
        try:
            file = queue.get(timeout=3)
            print('{}保存成功'.format(file))
        except:
            print('全部打印完毕')
            break

if __name__ == '__main__':
    q = Queue(5)
    p1 = Process(target=download,args=(q,))
    p2 = Process(target=getfile,args=(q,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print('end')

 

线程

线程状态: 
新建---(start)--->就绪--->运行---(此处若阻塞,即sleep,则让出进程空间,返回就绪状态)--->结束 
import threading 
threading.Thread(target= , name= ) 
th.start() 
th.join()

 

全局解释器锁GIL

当共享数据时,由于线程运行过程中可能存在阻塞,导致抢行,产生数据不安全 
全局解释器锁GIL(global interpreter lock):线程同步,保护执行中的线程,防止线程抢行导致的数据不同步,但是会牺牲运行速度

#线程:

import threading
import time

lock = threading.Lock()      #创建锁
list1 = [0]*10

def task1():                 #获取线程锁,如果锁被占用,则等待锁的释放
    lock.acquire()           #阻塞
    for i in range(len(list1)):    #共享数据的处理放在acquire与release之间
        list1[i]=i
        time.sleep(0.5)
    lock.release()           #释放锁,如果不释放,其他线程无法进入执行状态

def task2():
    lock.acquire()
    for i in range(len(list1)):
        print(i)
        time.sleep(0.5)
    lock.release()

if __name__ == '__main__':
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task2)
    t1.start()
    t2.start()
    print(threading.current_thread())    #当前正在执行的线程
    print(threading.enumerate())         #所有执行及等待中的线程列表
    t1.join()        #提高一级优先级,优先执行
    t2.join()        #t1,t2相同优先级,高于main
    print(list1)

 

死锁

死锁:两个线程的执行过程中需要相互调用各自的锁,则线程1占据进程并等待锁2,而锁2的释放需要占据进程,但此时需要等待线程1释放 
解决方法:

    1、重构代码 
    2、acquire(timeout= )设置占据时间上限,等待过长则自动释放 release

#死锁

from threading import Thread,Lock
import time

lockA = Lock()
lockB = Lock()

class MyThread1(Thread):
    def run(self):
        if lockA.acquire():
            print(self.name+'获取了A锁')
            time.sleep(0.1)
            if lockB.acquire():
                print(self.name+'又获取了B锁,原来还有A锁')
                lockB.release()
        lockA.release()

class MyThread2(Thread):
    def run(self):
        if lockB.acquire():
            print(self.name+'获取了B锁')
            time.sleep(0.1)
            if lockA.acquire():
                print(self.name+'又获取了A锁,原来还有B锁')
                lockA.release()
        lockB.release()

if __name__ == '__main__':
    th1 = MyThread1()
    th2 = MyThread2()
    th1.start()    
    th2.start()

 

生产者与消费者

生产者与消费者:两个线程之间的通信 
不一定生产一个吃一个,属于抢夺行为

1、通过加锁保证数据安全

#生产者与消费者Lock版

import random
import threading
import time

Money = 10000
Lock = threading.Lock()
Time = 0

class Producer(threading.Thread):
    def run(self):
        global Money
        global Time
        while True:
            produce = random.randint(500,1000)
            Lock.acquire()
            if Time >= 10:
                Lock.release()
                break
            else:
                Money += produce
                print('生产者%s生产了%d元钱,总共%d元钱'%(threading.current_thread(),produce,Money))
                Time+=1
                Lock.release()
                time.sleep(0.5)

class Consumer(threading.Thread):
    def run(self):
        global Money
        while True:
            consume = random.randint(1,2000)
            Lock.acquire()
            if Money < consume and threading.Thread.is_alive(th) != True:
                print('消费者%s准备消费%d元钱,但是只剩%d元钱,钱不够'%(threading.current_thread(),consume,Money))
                Lock.release()
                break
            else:
                Money -= consume
                print('消费者%s消费了%d元钱,还剩%d元钱'%(threading.current_thread(),consume,Money))
                Lock.release()
                time.sleep(0.5)

if __name__ == '__main__':
    th = Producer(name='生产者%d'%Time)
    th.start()
    tc = Consumer(name='消费者')
    tc.start()
    print(threading.Thread.is_alive(th))
    while True:
        if threading.active_count() == 1:
            print('='*30+'end'+'='*30)
            break

 

2、通过condition进行数据保护,线程待机等待唤醒的方式保证数据安全

#生产者和消费者condition版线程待机等待唤醒

import random
import threading
import time
Money = 10000

Condition = threading.Condition()
Time = 0

class Producer(threading.Thread):
    def run(self):
        global Money
        global Time
        while True:
            produce = random.randint(500,1000)
            Condition.acquire()
            if Time >= 10:
                Condition.release()
                break
            else:
                Money += produce
                print('生产者%s生产了%d元钱,总共%d元钱'%(threading.current_thread(),produce,Money))
                Time += 1
                Condition.notify_all()    #通知所有等待中的线程
                Condition.release()
                time.sleep(0.5)

class Consumer(threading.Thread):
    def run(self):
        global Money
        while True:
            consume = random.randint(1,2000)
            Condition.acquire()
            while Money < consume:
                print('消费者%s准备消费%d元钱,但是只剩%d元钱,钱不够'%(threading.current_thread(),consume,Money))
                if not threading.Thread.is_alive(th):
                    Condition.release()
                    return        #跳出所有循环
                Condition.wait()      #等待
            Money -= consume
            print('消费者%s消费了%d元钱,还剩%d元钱'%(threading.current_thread(),consume,Money))
            Condition.release()
            time.sleep(0.5)

if __name__ == '__main__':
    th = Producer(name='生产者%d'%Time)
    th.start()
    tc = Consumer(name='消费者')
    tc.start()
    print(threading.Thread.is_alive(th))         #判断th线程是否处于有效状态
    while True:
        if threading.active_count() == 1:        #除主线程外无其他有效线程
            print('='*30+'end'+'='*30)
            break

 

3、设置中间介queue队列,保证数据安全

FIFO:先入后出队列

LIFO:先出后入队列​

队列与堆栈取出数据的顺序相反,队列通常是先入先出,堆栈则是后入先出

#生产者和消费者Queue版线程安全队列
#队列等于排队,先到先得,先进入队列的会先被取走
#堆栈等于叠碟,后到先走,后进入堆栈的会先被取走

import threading
from queue import Queue
import time
import random

Time = 0
Condition = threading.Condition()
fruits = ['苹果','梨子','香蕉','荔枝','西瓜','榴莲','桃子']

def Producer(q):
    global Time
    while True: 
        produce = random.choice(fruits)
        Condition.acquire()
        if Time >= 10:
            Condition.notify_all()    #通知所有等待中的线程
            Condition.release()
            break
        else:
            q.put(produce)
            print('生产者%s生产了%s'%(threading.current_thread(),produce))
            Time += 1
            Condition.notify_all()    #通知所有等待中的线程
            Condition.release()
            time.sleep(random.random())

def Consumer(q):
    while True:
        Condition.acquire()
        while q.empty():
            print('消费者%s准备吃水果,但是没有了'%(threading.current_thread()))
            if not threading.Thread.is_alive(tp):
                Condition.release()
                return    #跳出所有循环
            Condition.wait()#等待
        consume = q.get()
        print('消费者%s吃了%s,还剩%d个水果'%(threading.current_thread(),consume,q.qsize()))
        Condition.release()
        time.sleep(0.7)

q = Queue(10)
tp = threading.Thread(target=Producer,args=(q,))
tc = threading.Thread(target=Consumer,args=(q,))
tp.start()
tc.start()
while True:
    if threading.active_count() == 1:
        print('='*30+'end'+'='*30)
        break

 

协程

 greenlet版

#协程 pip install greenlet

import time
from greenlet import greenlet

def taskA():
    for i in range(5):
        print('A',i)
        gb.switch()    #阻塞前启动协程b,释放空间
        time.sleep(0.5)

def taskB():
    for i inrange(5):
        print('B',i)
        gc.switch()    #阻塞前启动协程c,释放空间
        time.sleep(0.5)

def taskC():
    for i in range(5):
        print('C',i)
        ga.switch()    #阻塞前启动协程a,释放空间
        time.sleep(0.5)

if __name__ == '__main__':
    ga = greenlet(taskA)
    gb = greenlet(taskB)
    gc = greenlet(taskC)
    ga.switch()
    gb.switch()
    gc.switch()

 

gevent版

通过猴子补丁进行协程自动分配

#协程 pip install gevent 自动切换行程,不用等待IO

import time
import gevent
from gevent import monkey

monkey.patch_all()    #猴子补丁:感知耗时操作,自动替换所有阻塞操作,让协程自动切换

def taskA():
    for i in range(5):
        print('A',i)
        time.sleep(0.5)

def taskB():
    for i in range(5):
        print('B',i)
        time.sleep(0.5)

def taskC():
    for i in range(5):
        print('C',i)
        time.sleep(0.5)

if __name__ == '__main__':
    ga = gevent.spawn(taskA)
    gb = gevent.spawn(taskB)
    gc = gevent.spawn(taskC)
    ga.join()
    gb.join()
    gc.join()

 

正则表达式

正则表达式 Regular Expression。用于验证字符串的逻辑公式,简称re

特点: 给定一个正则表达式和另一个字符串,可以达到以下目的:

         1、给定的字符串是否符合正则表达式的过滤逻辑(称为‘匹配’)

         2、可以通过正则表达式,从字符串中获取我们想要的特定部分​

 

re模块函数:

match从开头匹配一次
search顺序查找,只匹配一次
findall顺序查找全部,遍历所有
sub按照 (正则, 新内容, 原内容) 进行替换
split在正则处分割,返回剩余部分组成的列表

 

常用正则表达式:

\A:     表示从字符串的开始处匹配 
\Z:     表示从字符串的结束处匹配,如果存在换行,只匹配到换行前的结束字符串 
\b:     匹配一个单词边界,也就是指单词和空格间的位置。例如,'py\b'可以匹配'python'中的'py',但不能匹配'openpyxl'中的'py' 
\B:     匹配非单词边界。'py\B'可以匹配'openpyxl'中的'py',但不能匹配'python'中的'py' 
\d:     匹配任意数字,等价于[0-9]                                   digit 
\D:     匹配任意非数字字符,等价于[^\d]                        not digit 
\s:      匹配任意空白字符,等价于[\t\n\r\f]                      space 
\S:      匹配任意非空白字符,等价于[^\s]                        not space 
\w:     匹配任意字母数字及下划线,等价于[a-zA-Z0-9_]  word 
\W:    匹配任意非字母数字及下划线,等价于[^\w] 
\:       转义,将后面的第一个字符取消其特殊意义 
\\:      匹配原义的反斜杠\ 
. :       匹配除换行符(\n)以外的所有字符 
^:      匹配字符串的开始,即行首 
         中括号内表示取逻辑非,例如,[^0-9]等价于除了0-9以外的其他字符 
$:       匹配字符串的末尾,(末尾如果有换行符\n,就匹配\n前面的那个字符),即行尾 
*:       按前面的匹配模式,匹配0次或多次(贪婪模式,即尽可能多的匹配),>=0 (判断:不能出现其他内容) 
+:      按前面的匹配模式,匹配1次或多次(贪婪模式),>=1 (判断:必须出现) 
?:       按前面的匹配模式,匹配0次或1次(贪婪模式),0,1 (判断:可有可无,查询:非贪婪,选择最短字符串) 
|:        或者,条件并列。小括号内表示整体或,例如,(abc|def)等价于abc或def 
                                     中括号内表示字符或,例如,[abc|def]等价于a、b、c、|、d、e或f 
{m}:    验证按前面的匹配模式,匹配m次 
{m,}:   验证按前面的匹配模式,匹配m次或多次 >=m 
{m,n}: 验证按前面的匹配模式,匹配m次以上,n次以下 >=m,<=n 
在*,?,+,{m,n}后面加?,转换为非贪婪,总是尝试匹配尽可能少的数据

 

正则表达式应用举例

import re

msg1 = 'jack334c2#^2jerry2km*&'
print(re.match(r'jack',msg1))          #match从头开始匹配,匹配成功则返回,否则返回None
print(re.match(r'[0-9a-zA-Z_]{3,}',msg1))   
#match从头开始匹配,由数字、字符或下划线组成,3位及以上

print(re.search(r'jerry',msg1))                      #search顺序查找匹配
print(re.search(r'jerry',msg1).span())               #匹配成功位置
print(re.search(r'[a-z][0-9][a-z]',msg1).group())    #匹配成功的内容部分,首中即停
print(re.findall(r'[a-z][0-9]+[a-z]',msg1))          #匹配成功的内容部分,找完为止
print(re.search(r'^[a-zA-Z]\w{3,}$',msg1))
#search顺序查找匹配,从头开始到末尾,以字符开头,由数字、字符或下划线组成,4位及以上

msg2 = 'a*pyb.pycc.pyd.txtepython.txt'
print(re.findall('\w*.py\\b',msg2))
#find查找所有,数字字符下划线+除换行符以外任意字符+py,且满足单词边界的字符串
#无r开头,加\表示\b不是字符格式,而是正则格式
print(re.findall(r'\w*\.py\b',msg2))
#find查找所有,数字字符下划线+.+py,且满足单词边界的字符串
#有r开头,加入\表示.不是正则格式(任意非换行字符),而是.字符
print(re.sub(r'py\b','txt',msg2))    #按正则替换

#0-100数字正则
text = '100'
print(re.match(r'\d?\d$|^100$',text))

#手机号码正则
phone = input('请输入电话号码')
if re.match('1[35789]\d{9}$',phone) != None:
    print('输入成功')
else:
    print('号码错误')

#邮箱正则
email = '123456789@qq.com'
print(re.match(r'\w{5,20}@(126|163|qq)\.(com|cn)$',email))

#URL正则
url = 'http://www,hao123.com'
print(re.match(r'(ftp|http|https)://\S+',url))

#爬虫正则
msg3 = '<html><h1>abc</h1></html>'
print(re.match(r'<(?P<name1>\w+)><(?P<name2>\w+)>(.+)</(?P=name2)></(?P=name1)>',msg3))
#用起名的方式进行重复项正则,(?P<名字>正则)...(?P=名字)
result1 = re.match(r'<(\w+)><(\w+)>(.+)</(\2)></(\1)>',msg3)
#进行分组,个别组的数据相同,后组引用前组内容
print(re.sub(r'<.+?>','',msg3))
print(result1)
print(result1.group(3))        #提取分组中第三组的数据,若索引为0表示返回整个数据
print(result1.group(1,2))
print(result1.groups())

#菜品涨价
def price_change(price):        #菜品价格低于10元,则涨价1元
    num = int(price.group())
    if num < 10:
        num += 1
        return str(num)

pricelist = '白菜5元,香菇9元,上海青12元'
print(re.sub(r'\d+',price_change,pricelist))    #对菜品价格正则替换
print(re.split(r'\d+元,?',pricelist))    #正则剪切出菜品名
result2 = re.findall(r',?(\D+)(\d+)元',pricelist)    
#利用()进行分组得到元组,利用元组获得菜品列表
print([i[0] for i in result2])
msg4 = 'thenumberis20.50'
r = re.compile(r"""\d+    #小数点前数字
                   \.?    #小数点
                   \d*    #小数点后面的数字
                """,re.VERBOSE)    #匹配格式,VERBOSE可以在后面注释

result3 = re.search(r,msg4)        #按照r的格式对msg4进行匹配
print(result3.group())

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值