Day6 - Python基础6 模块shelve、xml、re、subprocess、pymysql
本节目录:
1.shelve模块
2.xml模块
3.re模块
4.subprocess模块
5.logging模块
6.pymysql
1.shelve 模块
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
import shelve
d = shelve.open('shelve_test') #打开一个文件
class Test(object):
def __init__(self,n):
self.n = n
t = Test(123)
t2 = Test(123334)
name = ["alex","rain","test"]
d["test"] = name #持久化列表
d["t1"] = t #持久化类
d["t2"] = t2
d.close()
2.xml模块
3.re模块
正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,在文本处理方面功能非常强大,也经常用作爬虫,来爬取特定内容,Python本身不支持正则,但是通过导入re模块,Python也能用正则表达式,下面就来讲一下python正则表达式的用法。
一、匹配规则

二、findall
findall(),可以将匹配到的结果以列表的形式返回,如果匹配不到则返回一个空列表,下面来看一下代码中的使用
import re
l=re.findall(r'\d','4g6gggg9,9') # \d代表数字,将匹配到的元素放到一个列表里
print(l) # ['4', '6', '9', '9'] print(re.findall(r'\w','ds.._ 4')) # ['d', 's', '_', '4'],匹配字母数字下划线 print(re.findall(r'^sk','skggj,fd,7')) # 以sk开头的,['sk'] print(re.findall(r'^sk','kggj,fd,7')) # [] print(re.findall(r'k{3,5}','ffkkkkk')) # 取前面一个字符‘k'的3到5次,['kkkkk'] print(re.findall(r'a{2}','aasdaaaaaf')) # 匹配前一个字符a两次,['aa', 'aa', 'aa'] print(re.findall(r'a*x','aaaaaax')) # ['aaaaaax'] 匹配前面一个字符0次或多次,贪婪匹配 print(re.findall(r'\d*', 'www33333')) # ['', '', '', '33333', ''] print(re.findall(r'a+c','aaaacccc')) # ['aaaac'] 匹配前面一个字符的一次或多次,贪婪匹配 print(re.findall(r'a?c','aaaacccc')) # ['ac', 'c', 'c', 'c'] 匹配前面一个字符的0次或1次 print(re.findall(r'a[.]d','acdggg abd')) # .在[]里面失去了意义,所以结果为[] print(re.findall(r'[a-z]','h43.hb -gg')) # ['h', 'h', 'b', 'g', 'g'] print(re.findall(r'[^a-z]','h43.hb -gg')) # 取反,['4', '3', '.', ' ', '-'] print(re.findall(r'ax$','dsadax')) # 以'ax'结尾 ['ax'] print(re.findall(r'a(\d+)b','a23666b')) # ['23666'] print(re.findall(r'a(\d+?)b','a23666b')) # ['23666']前后均有限定条件,则非贪婪模式失效 print(re.findall(r'a(\d+)','a23b')) # ['23'] print(re.findall(r'a(\d+?)','a23b')) # [2] 加上一个?变成非贪婪模式
总结:findall 默认是匹配所有的,返回所以匹配到的一个列表,但是注意的是当有分组的时候,匹配还是按照匹配规则去,返回内容的时候,只包含了分组里面的内容。
三、match和search
match从要匹配的字符串的开头开始,尝试匹配,如果字符串开始不符合正则表达式,则匹配失败,函数返回None,匹配成功的话用group取出匹配的结果,search和mach很像,search是匹配整个字符串直道匹配到一个就返回。下面看下代码。
mport re print(re.match(r'a\d','a333333a4').group()) # a3,匹配到第一个返回 print(re.match(r'a\d','ta333333a4')) # 字符串开头不满足要求,返回一个None print(re.search(r'a\d','ta333333a4').group()) # a3 整个字符串匹配不需要从开头匹配 print(re.search(r'a(\d+)','a23b').group()) # a23 这里需要注意的是group()返回的是整个匹配到的字符串,如果是group(1)的话就只返回 23 了 print(re.search(r'a(\d+?)','a2366666666666b').group()) # a2 非贪婪模式 print(re.search(r'a(\d+)b','a23666b').group(1)) # 23666 group(1)返回第一个组
四、split、sub和subn
split能够将匹配的子串分割后返回列表,sub能将匹配到的字段用另一个字符串替换返回替换后的字符串,subn还返回替换的次数,下面再代码上看一下他们的用法
import re
print(re.split(r'\d','sd.4,r5')) # 以数字分割,注意第二次以'5'分割的时候,后面有一个空格 ['sd.',',r','']
print(re.sub(r'\d','OK','3,4sfds.6hhh')) # OK,OKsfds.OKhhh
print(re.sub(r'\d','OK','3,4sfds.6hhh',2)) # 2表示指定替换两次 OK,OKsfds.6hhh
print(re.subn(r'\d','OK','3,4sfds.6hhh')) # ('OK,OKsfds.OKhhh', 3) 将替换的次数也返回了
五、原生字符串、编译、分组
1、原生字符串
细心的人会发现,我每一次在写匹配规则的话,都在前面加了一个r,为什么要这样写,下面从代码上来说明,
import re
#“\b”在ASCII 字符中代表退格键,\b”在正则表达式中代表“匹配一个单词边界”
print(re.findall("\bblow","jason blow cat")) #这里\b代表退格键,所以没有匹配到 print(re.findall("\\bblow","jason blow cat")) #用\转义后这里就匹配到了 ['blow'] print(re.findall(r"\bblow","jason blow cat")) #用原生字符串后就不需要转义了 ['blow']
2、编译
如果一个匹配规则,我们要使用多次,我们就可以先将其编译,以后就不用每次都在去写匹配规则,下面来看一下用法
import re
c=re.compile(r'\d') #以后要在次使用的话,只需直接调用即可
print(c.findall('as3..56,')) #['3', '5', '6']
3、分组
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组,可以有多个组,分组的用法很多,这里只是简单的介绍一下
import re
print(re.findall(r'(\d+)-([a-z])','34324-dfsdfs777-hhh')) # [('34324', 'd'), ('777', 'h')] print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(0)) # 34324-d 返回整体
print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(1)) # 34324 获取第一个组
print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(2)) # d 获取第二个组
print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(3)) # IndexError: no such group print(re.search(r"(jason)kk\1","xjasonkkjason").group()) #\1表示应用编号为1的组 jasonkkjason print(re.search(r'(\d)gg\1','2j333gg3jjj8').group()) # 3gg3 \1表示使用第一个组\d # 下面的返回None 为什么是空?而匹配不到3gg7,因为\1的不仅表示第一组,而且匹配到的内容也要和第一组匹配到的内容相同,第一组匹配到3,第二组匹配到7 不相同所以返回空
print(re.search(r'(\d)gg\1','2j333gg7jjj8')) print(re.search(r'(?P<first>\d)abc(?P=first)','1abc1')) # 1abc1 声明一个组名,使用祖名引用一个组 r=re.match('(?P<n1>h)(?P<n2>\w+)','hello,hi,help') # 组名的另外一种用法
print(r.group()) # hello 返回匹配到的值
print(r.groups()) # ('h', 'ello')返回匹配到的分组
print(r.groupdict()) # {'n2': 'ello', 'n1': 'h'} 返回分组的结果,并且和相应的组名组成一个字典 # 分组是从已经匹配到的里面去取值
origin ="hello alex,acd,alex"
print(re.findall(r'(a)(\w+)(x)',origin)) # [('a', 'le', 'x'), ('a', 'le', 'x')]
print(re.findall(r'a\w+',origin)) # ['alex', 'acd', 'alex']
print(re.findall(r'a(\w+)',origin)) # ['lex', 'cd', 'lex']
print(re.findall(r'(a\w+)',origin)) # ['alex', 'acd', 'alex']
print(re.findall(r'(a)(\w+(e))(x)',origin)) # [('a', 'le', 'e', 'x'), ('a', 'le', 'e', 'x')] r=re.finditer(r'(a)(\w+(e))(?P<name>x)',origin)
for i in r :
print(i,i.group(),i.groupdict())
'''
[('a', 'le', 'e', 'x'), ('a', 'le', 'e', 'x')]
<_sre.SRE_Match object; span=(6, 10), match='alex'> alex {'name': 'x'}
<_sre.SRE_Match object; span=(15, 19), match='alex'> alex {'name': 'x'}
''' print(re.findall('(\w)*','alex')) # 匹配到了alex、但是4次只取最后一次即 x 真实括号只有1个
print(re.findall(r'(\w)(\w)(\w)(\w)','alex')) # [('a', 'l', 'e', 'x')] 括号出现了4次,所以4个值都取到了 origin='hello alex sss hhh kkk'
print(re.split(r'a(\w+)',origin)) # ['hello ', 'lex', ' sss hhh kkk']
print(re.split(r'a\w+',origin)) # ['hello ', ' sss hhh kkk']
五、综合练习
检测一个IP地址,比如说192.168.1.1,下面看下代码怎么实现的
c=re.compile(r'((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){3}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
print(c.search('245.255.256.25asdsa10.11.244.10').group()) # 10.11.244.10 245.255.256.25不符合要求所以就没有匹配出来
这里来解释下上面的匹配规则,先看 (1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.),其中1\d\d表示匹配100-199的数字 | 代表或的意思,2[0-4]\d代表匹配100-249,25[0-5]代表匹配250-255,[1-9]\d|\d)代表匹配10-99和0-9,\.代表匹配一个点,{3}代表将前面的分组匹配3次,后面的一部分类似就不说明了。要匹配一个ip重要的是先理解ip每个字段的形式,然后再来写匹配规则。此外有兴趣的话,还可以去看我Python实战目录里面计算器的实现,里面用到了正则。
4.subprocess模块
那么subprocess模块是做什么的?他可以指定shell 去执行命令
输出到屏幕:
import subprocess
subprocess.Popen('dir',shell=True) #指定shell 去解释'dir'这个命令

##注意subprocess 是一个程序 而 屏幕又是另一个的程序,可以看到的执行结果是subprocess的执行结果直接交给了屏幕输出
输出到管道:
>>> res = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
指定了subprocess的执行结果,输出到管道中去,而你要是想要数据就直接通过subprocess的对象到管道中去取
subprocess 可以有三个管道:
stderr = subprocess.PIPE ##标准输出
stdin = subprocess.PIPE ##标准输入
stdout = subprocess.PIPE ##错误输出
去管道取数据:
>>> res.stdout.read()
##去管道取得数据 默认是对应系统编码的字节码,记住:他取完就没有了。
5.logging模块
一 (简单应用)
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
输出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
可见,默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默认的日志格式为日志级别:Logger名称:用户输出消息。
二 灵活配置日志级别,日志格式,输出位置
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='/tmp/test.log',
filemode='w') logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
输出:
Thu, May :: a1.py[line:] DEBUG debug message
Thu, May :: a1.py[line:] INFO info message
Thu, May :: a1.py[line:] WARNING warning message
Thu, May :: a1.py[line:] ERROR error message
Thu, May :: a1.py[line:] CRITICAL critical message
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为-可用参数有:
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “-- ::,”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
三 logger对象
我们看过金庸的很多小说,其中呢 最厉害的武功应该就是吸星大法了!会吸星大法的人呢,可以吸收别人武功为己用。
import logging ##这样我们就创建了一个会吸星大法的人
logger = logging.getLogger() # 创建一种能够向文件写入日志的武功
fh = logging.FileHandler('test.log') # 创建一种能够向屏幕输出日志的武功
ch = logging.StreamHandler() # 创建一种输入日志的格式是怎么样的
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ##两种武功分别吃掉格式
fh.setFormatter(formatter)
ch.setFormatter(formatter) ##这个会吸星的再吃掉两种武功,就具有了两个的功力了
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch) ##剩下的就logger这个人存活着,使用logger做各种动作
logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')
这里有两个注意点:
(1):Logger是一个树形层级结构我们是可以给Logger起名字的,默认就是祖先root。
logger = logging.getLogger() ##祖先
logger2 = logging.getLogger("mylogger") ##儿子
logger3 = logging.getLogger("mylogger.next") ## 孙子
名字是唯一的,要是你创建了如下两个对象:但是呢 其实都是同一个对象,且输出的级别为ERROR
logger2 = logging.getLogger("mylogger") ##创建了logger2对象,级别为INFO
logger2.setLevel(logging.INFO)
logger3 = logging.getLogger("mylogger") ##创建了logger3对象,级别为ERROR
logger3.setLevel(logging.ERROR)
(2):还需要注意的是,要是当给的名字,存在父辈的时候,上面有几个父辈就没个级别的日志就打印几次。
如下代码:请输入你的猜想是什么?
import logging logger = logging.getLogger()
logger.setLevel(logging.DEBUG) logger1 = logging.getLogger('mylogger')
logger1.setLevel(logging.INFO) fh = logging.FileHandler("FILE.LOG")
ch = logging.StreamHandler() logger.addHandler(fh)
logger.addHandler(ch) logger1.addHandler(fh)
logger1.addHandler(ch) logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message') logger1.debug('logger1 debug message')
logger1.info('logger1 info message')
logger1.warning('logger1 warning message')
logger1.error('logger1 error message')
logger1.critical('logger1 critical message')
是不是可以说,logger打印五条?logger1打印5条信息?其实并不是。请看结果:
logger debug message
logger info message
logger warning message
logger error message
logger critical message
logger1 info message
logger1 info message
logger1 warning message
logger1 warning message
logger1 error message
logger1 error message
logger1 critical message
logger1 critical message
会发现logger1会多打印出一次相同的信息,这是因为logger1上面存在了一个父辈root,要记得存在几个父辈就多打印几次。
6.pymysql
python关于mysql的API--pymysql模块
pymsql是Python中操作MySQL的模块,其使用方法和py2的MySQLdb几乎相同。
模块安装
pip install pymysql
执行sql语句
import pymysql #添加数据 conn = pymysql.connect(host='127.0.0.1', port=, user='root', passwd='', db='yyy') cursor = conn.cursor() ####创建游标,游标可以理解成在cmd中一闪一闪的光标 # sql = """CREATE TABLE EMPLOYEE (
# FIRST_NAME CHAR() NOT NULL,
# LAST_NAME CHAR(),
# AGE INT,
# SEX CHAR(),
# INCOME FLOAT )"""
#
# cursor.execute(sql) ###他是有返回值的 row_affected 就是这次操作受到影响的行数
#row_affected = cursor.execute("create table t1(id INT ,name VARCHAR(20))") #row_affected=cursor.execute("INSERT INTO t1(id,name) values (1,'alvin'),(2,'xialv')") #cursor.execute("update t1 set name = 'silv2' where id=2") #查询数据 cursor和文件的光标是一致的,取完数据就取完了
row_affected=cursor.execute("select * from t1")
one=cursor.fetchone() ##取到查询到的一条数据 # many=cursor.fetchmany() ##取到2条数据。
# all=cursor.fetchall() ##取到查询到的所有数据 #scroll 移动光标 #print(cursor.fetchone()) #(,)
#cursor.scroll(-,'relative') #相对当前位置移动 - 向上移动一个
#print(cursor.fetchone()) #(,) #print(cursor.fetchone()) #(,)
#cursor.scroll(,'relative') #相对当前位置移动 跳过下一下
#print(cursor.fetchone()) #(,) #cursor.scroll(,mode='absolute') # 相对绝对位置移动 #更改获取数据结果的数据类型,默认是元组,可以改为字典等:conn.cursor(cursor=pymysql.cursors.DictCursor) conn.commit()
cursor.close()
conn.close()
Day6 - Python基础6 模块shelve、xml、re、subprocess、pymysql的更多相关文章
- python基础——第三方模块
python基础——第三方模块 在Python中,安装第三方模块,是通过包管理工具pip完成的. 如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了. 如果你正在使用Window ...
- python基础——使用模块
python基础——使用模块 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用. 我们以内建的sys模块为例,编写一个hello的模块: #!/usr/bin/env ...
- python学习之路-7 模块configparser/xml/shutil/subprocess以及面向对象初级入门
本篇记录内容 模块 configparser xml shutil subprocess 面向对象 面向对象基础 面向对象编程和函数式编程对比 面向对象中对象和类的关系 面向对象之构造方法 面向对象之 ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- python 基础之 模块
Python 基础之模块 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文 ...
- python模块(shelve,xml,configparser,hashlib,logging)
1.1shelve模块 shelve 模块比pickle模块简单,只有一个open函数,返回类似字典对象,可读可写:key必须为字符串, 而值可以是python所支持的数据类型. shelve模块主要 ...
- Python模块 shelve xml configparser hashlib
常用模块1. shelve 一个字典对象模块 自动序列化2.xml 是一个文件格式 写配置文件或数据交换 <a name="hades">123</a>3. ...
- python基础-7模块,第三方模块安装方法,使用方法。sys.path os sys time datetime hashlib pickle json requests xml
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- Day6 Python常用的模块
一.logging模块 一.日志级别 critical=50 error=40 waring=30 info=20 debug=10 notset=0 二.默认的日志级别是waring(30),默认的 ...
随机推荐
- 【解决】Failed to restart network.service: Unit network.service not found.
问题:使用systemctl restart network 或 service network restart 命令重启网卡失败. 分析:原因其实也很简单,命令用错了,造成了找不到相应的网卡服务. ...
- Mysql悲观锁乐观锁区别与使用场景
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- centos 下安装rabbitmq
1.先安装下依赖环境 yum install gcc glibc-devel make ncurses-devel openssl-devel xmlto 2.到earlang 官网下载erlang包 ...
- js-函数的三种创建方式
1.声明式 function fn() { //do something } 2.函数表达式 let fn = function () { //do something } 3.构造函数 functi ...
- NestedScrollView、ScrollView 加载完自动滑动至底部问题的解决方案
正常情况下,由于NestedScrollView/ScrollView 嵌套RecyclerView,可能会导致Recyclerview占据焦点导致整个NestedScrollView/ScrollV ...
- 发送RCS 消息摘录相关成功log
//11-25 16:48:09.612102 2175 2726 I BugleDataModel: PendingMessagesProcessor: process from InsertN ...
- Flutter学习笔记(22)--单个子元素的布局Widget(Container、Padding、Center、Align、FittedBox、Offstage、LimitedBox、OverflowBox、SizedBox)
如需转载,请注明出处:Flutter学习笔记(22)--单个子元素的布局Widget(Container.Padding.Center.Align.FittedBox.Offstage.Limited ...
- Mac中 pip3 install mysqlclient 报错
主要错误提示如下: ld: library not found for -lssl clang: error: linker command failed with exit code 1 (use ...
- [Go] 使用net包作为tcp客户端读取http
1.tcp的客户端,并且直接读取http协议的全部内容,每次读取4096字节,直到最后一个字节是\n并且读取的长度小于4096 conn, err := net.Dial("tcp" ...
- Samba共享文件
1 安装samba yum install -y samba* 2 添加用户 useradd smbuser 3 设置共享文件用户的密码 smbpasswd -a smbuser 4 创建公共共享文件 ...