首页 > 代码库 > Python基础-第五天-常用模块
Python基础-第五天-常用模块
本篇内容:
1.sys模块
2.os模块
3.time模块和datetime模块
4.random模块和string模块
5.shutil模块
6.json模块和pickle模块
7.shelve模块
8.hashlib模块和hmac模块
9.logging模块
10.re模块
一、sys模块
1.sys模块简介
sys模块是Python标准库中自带了一个模块,sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境
2.sys模块的使用
①python的环境变量
print(sys.path) # 返回一个列表,显示出python默认的环境变量 sys.path.append(path) # 将导入文件或模块的路径添加到sys.path中,追加的方式添加; sys.path.insert(0, path) # 将导入文件或模块的路径添加到sys.path中,添加在列表的最前面;(推荐)
②获取命令行的参数
print(sys.argv) # 返回一个列表,第一个元素是脚本名,第二个元素是脚本后跟的第一个参数,以此类推 print(sys.argv[0]) # 返回脚本名 print(sys.argv[1]) # 返回脚本后跟的第一个参数 print(sys.argv[2]) # 返回脚本后跟的第二个参数
③标准输出
# linux上yum安装软件时进度条示例 for i in range(20): sys.stdout.write("#") # 将“#”通过标准输出显示到屏幕上 sys.stdout.flush() # 刷新内存,不然只能等到循环结束才能显示出内容 time.sleep(0.1) # 每隔0.1秒显示出内容
④其他用法
print(sys.version) # 显示出当前使用的python解释器版本信息 print(sys.platform) # 显示当前使用的是什么操作系统平台,windows会显示win32,linux会显示linux2 print(sys.getdefaultencoding()) # 显示系统默认字符编码 sys.exit(n) # 退出程序,n是返回值
二、os模块
1.os模块简介
os模块是Python标准库中自带了一个模块,os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。
2.os模块的使用
①与操作系统相关操作
print(os.name) # 查看当前使用的系统平台,Windows返回‘nt‘,Linux返回‘posix‘。 os.system(shell command) # 调用系统shell的命令,windows和linux都能使用。 print(os.environ) # 获取系统环境变量PATH,windows和linux都能使用。
②与目录相关操作
os.mkdir(directory) # 创建单级目录,相当于shell中mkdir dirname。 os.makedirs(directory1/directory2) # 递归生成多层目录; os.removedirs(directory1/directory2) # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推; os.rmdir(directory) # 删除指定目录,只能删除目录。只能删除单级空目录,若目录不为空,则无法删除,会报错。 print(os.path.isdir(directory)) # 判断指定对象是否为目录。是True,否则False; print(os.listdir(directory)) # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印; for root_path, directory, file in os.walk(directory): print("目录的绝对路径:", root_path) print("目录中的子目录:", directory) print("目录中的文件:", file) # os.walk能遍历目录中的文件。注意,会遍历目录中的子目录,一直到最后一级才会停止。 # root_path是一个string,为起始路径(即目录的绝对路径)。 # directory是一个list,为起始路径下的文件夹(即所在目录中的所有子目录)。 # file是一个list,为起始路径下的文件(即所在目录中的所有文件)。
③与文件相关操作
print(os.path.isfile(file)) # 判断指定对象是否为文件,要写成绝对路径的方式。是返回True,不是则返回False; os.remove(file) # 删除指定文件,只能删除文件。 print(os.path.getsize(file)) # 获取文件大小,空文件返回的是0,默认单位是字节。如果指定的是目录则返回0L; print(os.path.splitext(file)) # 返回一个包含两个元素的元组,第一个元素是文件名,第二个元素是文件的扩展名。
④目录和文件通用操作
os.rename(oldname, newname) # 文件或目录重命名; print(os.stat(directory or file)) # 获取文件或目录的信息,包括uid、gid、size等等;
⑤路径相关操作
print(os.path.exists(path)) # 如果路径存在,则返回True。如果路径不存在,则返回False; print(os.getcwd()) # 得到当前工作的目录(绝对路径),即当前Python脚本工作的目录路径。 os.chdir(dirname) # 改变当前脚本工作目录;相当于shell下cd; print(os.path.abspath(file)) # 返回文件规范化后的绝对路径; print(os.path.split("文件的绝对路径")) # 将文件的绝对路径分割成目录和文件名,放进元组后并返回; print(os.path.dirname("文件的绝对路径")) # 返回一个元组,即文件的绝对路径的目录部分。 print(os.path.basename("文件的绝对路径")) # 返回文件的绝对路径的文件名部分。如果路径是以"/"或"\"结尾,那么就会返回空值。 print(os.path.isabs(path)) # 如果路径是绝对路径,则返回True;不是绝对路径,则返回False; print(os.path.join(path1, path2, path3)) # 将多个路径组合后返回。注意,如果路径中存在绝对路径,绝对路径之前的参数将被忽略;
三、time模块和datetime模块
1.time模块使用
print(time.time()) # 时间戳,显示的是从1970年1月1日00:00:00开始到当前的浮点秒数。 print(time.localtime()) # 返回本地时间的struct time对象格式。参数只能接收秒; print(time.localtime(time.time() + 3600 * 3)) # 例如在当前时间基础上多加三小时 time.struct_time(tm_year=2017, tm_mon=7, tm_mday=17, tm_hour=19, tm_min=55, tm_sec=18, tm_wday=0, tm_yday=198, tm_isdst=0) time.sleep(seconds) # 延迟代码执行的作用。默认单位是秒。注意,在sleep的时间段内是不会占用CPU时间; # 按照自定义的格式显示当前时间 print(time.strftime("%Y-%m-%d %X")) # Y代表年,m代表月,d代表日,X代表小时分钟秒。 2017-07-17 17:09:40 string_struct_1 = time.strptime("2017/07/17","%Y/%m/%d") # 将字符串格式转成时间对象; struct_stamp_1 = time.mktime(string_struct_1) # 将时间对象转换成时间戳,转成时间戳后就可以做运算 string_struct_2 = time.localtime(struct_stamp_1) # 将时间戳转换成时间对象 string = time.strftime("%Y/%m/%d", string_struct_2) # 将时间对象转成字符串格式
2.datetime模块使用
# 返回本地时间,格式为“年-月-日 小时:分钟:浮点秒数”。返回的时间为日期时间类型; # 日期时间类型的时间能做运算 print(datetime.datetime.now()) print(datetime.datetime.now() + datetime.timedelta(minutes=30)) # 在当前时间基础上加30分钟 print(datetime.datetime.now() - datetime.timedelta(hours=3)) # 在当前时间基础上减3小时 print(datetime.datetime.now() + datetime.timedelta(3)) # 在当前时间基础上加3天,参数默认为天; print(datetime.datetime.now().replace(year=2018, month=1, day=1, hour=1, minute=1, second=1)) # 时间替换 2018-01-01 01:01:01.996065 print(datetime.datetime.strptime("2021-01-01", "%Y-%m-%d")) # 将字符串转换成日期时间类型 2021-01-01 00:00:00 print(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S")) # 将日期时间类型转换成字符串 2017-07-18_23:12:51 print(datetime.datetime.now().year) # 将日期时间类型的时间单独取出年,也可以取月、日、时、分、秒; 2017 # 通过replace直接对日期时间类型的时间进行修改,可以修改年月日时分秒。 after_5_years = datetime.datetime.now().year + 5 print(datetime.datetime.now().replace(year=after_5_years)) 2022-07-18 23:18:37.253450
四、random模块和string模块
1.random模块使用
random模块是生成随机数的模块
print(random.random()) # 随机打印一个小于一大于零的小数 0.8574527726862693 print(random.randint(1, 3)) # 从1、2、3三个数中随机打印出一个数,顾头顾尾 3 print(random.randrange(1, 3)) # 从1、2两个数中随机打印出一个数,顾头不顾尾 1 print(random.sample(range(100), 5)) # 在0到100之间随机打印出5个数,打印的5个数中不会有重复的数 [12, 66, 32, 64, 33] print("".join(random.sample("abcde12345", 5))) # 在abcde12345中随机打印出5个,打印的5个中不会有重复的 b2a3c
2.string模块使用
print(string.printable) # 获取所有字符,包括数字、大小写字母、特殊标点符号和空格符号 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&‘()*+,-./:;<=>?@[\]^_`{|}~ print(string.ascii_lowercase) # 获取小写字母 print(string.ascii_uppercase) # 获取大写字母 print(string.ascii_letters) # 获取大小写字母 print(string.digits) # 获取数字 print(string.ascii_letters + string.digits) # 将大小写字母和数字拼接在一起
五、shutil模块
1.shutil模块简介
shutil是一个能对文件、文件夹、压缩包处理的高级模块;
2.shutil模块对文件进行拷贝、移动和删除操作
①将文件内容拷贝到另一个文件中
with open("test01", "r", encoding="utf-8") as f_old, open("test02", "w", encoding="utf-8") as f_new: shutil.copyfileobj(f_old, f_new) # 将test01中的内容拷贝到test02中
②拷贝文件
shutil.copyfile("test01", "test02") # 拷贝test01并命名为test02。注意必须要有对test02写的权限;
③仅拷贝权限,内容、组、用户均不变,不拷贝状态信息。
shutil.copymode("test01", "test02") # 将test01的权限拷贝给test02。注意test02必须要存在;
④拷贝所有的状态信息,包括,组,用户,时间等,不拷贝权限信息。
shutil.copystat("test01", "test02") # 将test01的状态信息拷贝给test02。注意test02必须要存在;
⑤拷贝文件及权限
shutil.copy("test01", "test02") # 拷贝test01并命名为test02,也会拷贝test01的权限
⑥拷贝文件和文件的所有状态信息
shutil.copy2(src, dst)
⑦递归的去拷贝文件及状态信息
shutil.copytree(olddir, newdir, True/Flase)
把olddir及其中包含的文件拷贝成为newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接;
⑧删除文件
shutil.rmtree(path)
目录中如果没有包含文件,则删除目录。目录中如果包含文件了,则删除目录及目录内的所有文件。
⑨移动文件
shutil.move(src, dst)
目录中如果没有包含文件,则移动目录。目录中如果包含文件了,则移动目录及目录内的所有文件。
3.shutil模块对文件进行打包和压缩操作
shutil.make_archive(base_name, format, root_dir, owner, group, logger)
参数详解:
base_name:压缩包的文件名,可以是相对路径或绝对路径。当只写了文件名时,则保存至当前目录。如果写的是绝对路径加文件名,则保存至指定路径;如,www是保存至当前路径,/Users/wupeiqi/www是保存至/Users/wupeiqi/目录下,文件名是www。
format:压缩包种类,可以是“zip”, “tar”, “bztar”,“gztar”;
root_dir:要压缩的目录路径(默认当前目录)。注意,只能是目录;
owner:用户,默认当前用户;
group:组,默认当前组;
logger:用于记录日志,通常是logging.Logger对象;
六、json模块和pickle模块
什么是序列化和反序列化:
●把内存中的数据类型变成字符串后存储或传输的过程叫做序列化;
●把存储或传输的字符串变成内存中的数据类型的过程叫做反序列化;
1.json模块
json模块用于字符串和python数据类型间进行转换;
json模块只能处理python的字典、列表、字符串等简单的数据类型,不能处理函数。
①json模块序列化
●json.dump(),将内存对象转换后能直接存到文件中
with open("文件名", "w", encoding="字符编码") as 文件句柄: json.dump(内存对象, 文件句柄)
●json.dumps(),将内存对象转换为字符串,如果要保存到文件中,需要再对文件进行操作。
json.dumps(内存对象)
②json模块反序列化
●json.load(),从文件中取出数据后并再转换成内存对象。
with open("文件名", "r", encoding="字符编码") as 文件句柄: 内存对象 = json.load(文件句柄)
●json.loads(),先通过read()取出数据,然后再通过loads()将取出的数据转换成内存对象。
json.loads(取出的文件数据)
2.pickle模块
pickle模块用于python特有的类型和python的数据类型间进行转换。能处理python所有的数据类型,比如函数;
①pickle模块序列化
●pickle.dump(),将内存对象转换成字符串后并再保存到文件中。
with open("文件名", "wb") as 文件句柄: pickle.dump(obj, file即文件句柄, protocol=None, fix_imports=True)
参数详解:
protocol:为序列化使用的协议版本。0代表ASCII协议,所序列化的对象使用可打印的ASCII码表示。1代表老式的二进制协议。2是2.3版本引入的新二进制协议,较以前的更高效。其中协议0和1兼容老版本的python。缺省情况下,dumps()和dump()使用可打印的ASCII表示来创建pickle。
file:对象保存到的类文件对象。如果protocol >= 1,文件对象需要用二进制模式打开;
fix_imports:(可选),如果为True,则该参数指定用更快以及更小的二进制表示来创建 pickle。fix_imports参数默认为True,所以是用更小的二进制表示来创建 pickle。
●pickle.dumps(),将内存对象转换为字符串,如果要保存到文件中,需要再对文件进行操作。
pickle.dumps(obj, protocol=None, fix_imports=True)
参数详解:
protocol:为序列化使用的协议版本。0代表ASCII协议,所序列化的对象使用可打印的ASCII码表示。1代表老式的二进制协议。2是2.3版本引入的新二进制协议,较以前的更高效。其中协议0和1兼容老版本的python。缺省情况下,dumps()和dump()使用可打印的ASCII表示来创建pickle。
fix_imports:(可选),如果为True,则该参数指定用更快以及更小的二进制表示来创建 pickle。fix_imports参数默认为True,所以是用更小的二进制表示来创建 pickle。如果protocol >= 1,文件对象需要用二进制模式打开;
②pickle模块反序列化
●pickle.load(),从文件中取出数据后并再转换成内存对象。
with open("文件名", "rb") as 文件句柄: 内存对象 = pickle.load(文件句柄)
●pickle.loads(),先通过read()取出数据,然后再通过loads()将取出的数据转换成内存对象。
pickle.loads(取出的文件内容)
七、shelve模块
1.shelve模块简介
shelve模块是一个简单的key-value将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式;
shelve模块相比json模块和pickle模块不同之处是:shelve模块能dump多次,也能load多次。而json模块和pickle模块能dump多次,但只能load一次。
数据保存在三个文件中:文件名.bak、文件名.dat、文件名.dir,这三个文件保存的内容是一样的,只是采用的字符不一样。
2.shelve模块的使用
①序列化
import shelve d = shelve.open("shelve_test") # 打开文件,获取一个shelve对象。该文件是存储数据的文件。 info_dict = {"name": "alex", "age": "26"} info_list = [1, 2, "a", "b"] d["test_dict"] = info_dict # 自定义key,value是Python内存对象 d["test_list"] = info_list d.close() # 关闭文件
②反序列化
import shelve f = shelve.open("shelve_test") # 打开文件,获取一个shelve对象。该文件是存储数据的文件。 info_dict = f["test_dict"] # 取出value,value为Python内存对象 info_list = f["test_list"] f.close() # 关闭文件
八、hashlib模块和hmac模块
hash的特点:只要输入的内容是固定的,输出的内容就是固定的。
MD5是在hash基础上做的,只要文件内容没改动,MD5的值都是一样的。
通过MD5算法算出的值是不可逆的,即无法通过MD5值反解出明文内容。
1.hashlib模块
hashlib模块用于加密相关的操作,在Python 3.x版本中代替了md5模块和sha模块,主要提供 SHA1、SHA224、SHA256、SHA384、SHA512和MD5算法。
Python 3.x版本中hashlib模块只能处理bytes类型;
①hashlib模块使用MD5算法
●加密
import hashlib m = hashlib.md5() # 对hello进行md5 # Python 3.x版本中hashlib模块只能处理bytes类型 m.update(b"hello") print(m.digest()) # 以2进制格式显示 b‘]A@*\xbcK*v\xb9q\x9d\x91\x10\x17\xc5\x92‘ print(m.hexdigest()) # 以16进制格式显示 5d41402abc4b2a76b9719d911017c592
●比较文件一致性
import hashlib m = hashlib.md5() m.update(b"hello") print(m.hexdigest()) # 打印hello的md5值 5d41402abc4b2a76b9719d911017c592 m.update(b"hi") print(m.hexdigest()) # 打印hello和hi的md5值 71b37739883f2e3059b5c465e5b85f2e m2 = hashlib.md5() m2.update(b"hellohi") print(m2.hexdigest()) # 打印hello和hi的md5值 71b37739883f2e3059b5c465e5b85f2e
②SHA1算法、SHA224算法、SHA256算法、SHA384算法、SHA512算法
都是不同的MD5算法,但比MD5算法更安全
SHA256算法使用的也是最多的。SHA512算法是最安全,但加密花的时间最长
使用各种算法的语法都一样,这里以使用SHA1算法来举例
import hashlib m = hashlib.sha1() m.update(b"hello") print(m.hexdigest()) aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
③添加自定义key再来做加密,以SHA256算法举例
import hashlib m1 = hashlib.sha256() m1.update(b"hello") print(m1.hexdigest()) 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 m2 = hashlib.sha256(b"123abc!@#") # 添加key,注意key也转成bytes类型 m2.update(b"hello") print(m2.hexdigest()) 0b4e144bd09eba219d684a925315007b49c77e378cbc24e1bf13fbcaf3e4afef
2.hmac模块
hmac模块,它内部对我们创建的key和内容进行处理,然后再加密;
比SHA256算法还要快;
添加自定义key再来做加密
import hmac # 注意,需要加密的内容要转成bytes类型。添加的key也要转成bytes类型; # 括号中第一个是添加的key,第二个是需要加密的内容 h = hmac.new(b"123abc!@#", b"hello") print(h.hexdigest()) # 以16进制格式显示 106b0ebd740015cab746eedcda3bd88e
九、logging模块
1.logging模块简介
logging模块用于便捷记录日志且线程安全的模块;
很多程序都有记录日志的需求,并且日志中包含的信息有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,可以通过它存储各种格式的日志。
logging的日志级别从低到高依次可以分为 :debug()、info()、warning()、error()、critical()5个级别。只有大于等于当前日志等级的日志才会被记录或打印。
2.logging模块记录日志涉及四个主要类
①logger:提供了应用程序可以直接使用的接口,用户调用的时候直接调用logger。
每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名。
在上面所举的例子中,由于没有指定Logger,所以Logger则对应的是程序的模块名,即logging就是默认的logger,要通过logger来打印日志信息。
②handler:将(logger创建的)日志记录发送到合适的位置(屏幕、文件、远程机器、邮件)输出;
handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler。
③filter:提供了细度设备来决定输出哪条日志记录。例如,能过滤出包含指定字段的日志。这个功能用的比较少;
④formatter:决定日志记录的最终输出格式;
日志格式对象名 = logging.Formatter(format="格式代码", datefmt="指定的日期/时间格式"):定义输出到handler的日志格式。注意,fmt指定的格式代码之间还可以自定义添加字符串:
logging.Formatter()参数详解:
format指定的格式代码:
%(name)s:Logger的名字;
%(levelno)s:数字形式的日志级别。例如DEBUG的值是10;
%(levelname)s:文本形式的日志级别。例如DEBUG、WARNING等等;
%(pathname)s:调用日志输出函数的模块的完整路径名(绝对路径)。有可能没有;
%(filename)s:调用日志输出函数的模块的文件名。带.py;
%(module)s:调用日志输出函数的模块名。不带.py;
%(funcName)s:调用日志输出函数的函数名。没有函数的话,显示的是<module>;
%(lineno)d:调用日志输出函数的语句所在的代码行;
%(created)f:当前时间,用UNIX标准的表示时间的浮点数表示。
%(relativeCreated)d:输出日志信息时的,自Logger创建以来的毫秒数。
%(asctime)s:字符串形式的当前时间。默认格式是"2003-07-08 16:49:45,896"(逗号后面的是毫秒);
%(thread)d:线程ID。有可能没有;
%(threadName)s:线程名。有可能没有;
%(process)d:进程ID。有可能没有;
%(message)s:用户输出的消息;
datefmt:使用指定的日期/时间格式。当与format中的%(asctime)s共存时,以datefmt指定的日期/时间格式为准;常用日期/时间format代码如下:
%Y:年,以十进制数作为十进制的年。例如:2016、2017;
%y:年,例如16、17;
%m:月,十进制数[01,12];
%d:日,十进制数的日期[01,31];
%H:小时(24小时制),为十进制数[00,23];
%M:分钟,为十进制数[00,59];
%S:秒数,为十进制数[00,61];
%z:时区偏离UTC;
%a:地区的缩写工作日的名字;
%A:地区的完整工作日的名字;
%b:区域设置的缩写月份名称;
%B:区域设置的全月份名称;
%c:区域设置适当的日期和时间表示;
%I:小时(12小时制),为十进制数[01,12];
%p:地区相当于AM或PM;
3.实现日志即在屏幕上打印,又保存到文件中
import logging # 导入logging模块 Logger对象名 = logging.getLogger("自定义的名字") # 创建一个logger对象名 Logger对象名.setLevel(logging.日志级别) # 定义全局最低的日志级别 屏幕handler对象名 = logging.StreamHandler() # 创建屏幕的handler 屏幕handler对象名.setLevel(logging.日志级别) # 定义输出到屏幕上最低的日志级别 # 创建文件的handler,指定保存日志的文件,指定打开文件的字符编码; 文件handler对象名 = logging.FileHandler("文件名", encoding="字符编码") 文件handler对象名.setLevel(logging.日志级别) # 定义保存到文件中最低的日志级别 # 定义输出到屏幕的handler上的日志格式 屏幕日志格式对象名 = logging.Formatter(fmt="格式代码", datefmt="指定的日期/时间格式") # 将定义输出到屏幕上的格式与屏幕的handler关联起来 屏幕handler对象名.setFormatter(屏幕日志格式对象名) # 定义输出到文件的handler中的日志格式 文件日志格式对象名 = logging.Formatter(fmt="格式代码", datefmt="指定的日期/时间格式") # 将定义输出到文件中的格式与文件的handler关联起来 文件handler对象名.setFormatter(文件日志格式对象名) Logger对象名.addHandler(屏幕handler对象名) # 将屏幕的handler增加到logger中 Logger对象名.addHandler(文件handler对象名) # 将文件的handler增加到logger中 # 输出日志内容 Logger对象名.debug("日志内容") Logger对象名.info("日志内容") Logger对象名.warning("日志内容") Logger对象名.error("日志内容") Logger对象名.critical("日志内容")
4.将日志文件按大小截断
import logging from logging import handlers # 一定要单独导入handlers # 创建一个logger对象,自定义的名字为test log logger = logging.getLogger("test log") # 定义全局最低的日志级别 logger.setLevel(logging.DEBUG) # 创建文件的handler,指定日志保存在access.log文件中,设定日志文件最大为10字节,最多备份3个文件,以utf-8字符编码打开文件 file_handler = handlers.RotatingFileHandler(filename="access.log", encoding="utf-8", maxBytes=10, backupCount=3) # 定义保存到文件中最低的日志级别 file_handler.setLevel(logging.WARNING) # 定义输出到文件的handler中的日志格式 file_handler_formatter = logging.Formatter(fmt="%(asctime)s - %(lineno)d : %(message)s", datefmt="%Y-%m-%d_%H:%M:%S") # 将定义输出到文件中的格式与文件的handler关联起来 file_handler.setFormatter(file_handler_formatter) # 将文件的handler增加到logger中 logger.addHandler(file_handler) # 输出日志内容 logger.warning("test warning 01") logger.warning("test warning 02") logger.warning("test warning 03") logger.warning("test warning 04") logger.warning("test warning 05")
5.将日志文件按时间截断
import logging import time from logging import handlers # 一定要单独导入handlers # 创建一个logger对象,自定义的名字为test log logger = logging.getLogger("test log") # 定义全局最低的日志级别 logger.setLevel(logging.DEBUG) # 创建文件的handler,指定日志保存在access.log文件中,设定日志每间隔2秒截断一次,最多备份3个文件,以utf-8字符编码打开文件 file_handler = handlers.TimedRotatingFileHandler(filename="access.log", encoding="utf-8", when="S", interval=2, backupCount=3) # 定义保存到文件中最低的日志级别 file_handler.setLevel(logging.WARNING) # 定义输出到文件的handler中的日志格式 file_handler_formatter = logging.Formatter(fmt="%(asctime)s - %(lineno)d : %(message)s", datefmt="%Y-%m-%d_%H:%M:%S") # 将定义输出到文件中的格式与文件的handler关联起来 file_handler.setFormatter(file_handler_formatter) # 将文件的handler增加到logger中 logger.addHandler(file_handler) # 输出日志内容 logger.warning("test warning 01") time.sleep(2) # 因为设置的是2秒截断一次 logger.warning("test warning 02") time.sleep(2) logger.warning("test warning 03") time.sleep(2) logger.warning("test warning 04") time.sleep(2) logger.warning("test warning 05")
十、re模块
1.re模块简介
re模块用于对python的正则表达式的操作。
正则表示法就是处理字串的方法,他是以行为单位来进行字串的处理行为,正则表示法透过一些特殊符号的辅助,可以让使用者轻易的达到搜寻、删除、取代某特定字串的处理程序。
2.re模块的正则表达式符号
①匹配的字符
.:默认匹配除换行符以外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行;
\w:匹配的是[A-Za-z0-9]范围内的任意一个字符,即字母或数字或下划线或汉字;
\W:匹配的是非[A-Za-z0-9]范围内的任意一个字符,即非字母、非数字、非下划线、非汉字;
\s:匹配空白字符、\t、\n、\r,例如re.search("\s+","ab\tc1\n3").group(),结果为‘\t‘;
\d:匹配0到9之间任意一个数字;
\D:匹配非数字的字符;
\b:匹配单词的开始或结束;
|:匹配|号左的字符或者|号右的字符,re.search("abc|ABC", "ABCBabcCD").group(),结果为[‘ABC‘];
[开始值-结束值...]:匹配指定范围内的任意一个字符。例如[a-zA-Z]是匹配大小写字母中的任意一个字母;
[^字符]:中括号[^]中的^是非的意思,代表匹配除指定字符以外的字符;
②匹配的次数
*:匹配*号前一个字符0次或多次。注意*号可以匹配0次,不匹配的话,返回的不是None,而是‘‘。例如re.findall("ab*", "cabb3abcbbac"),结果为[‘abb‘, ‘ab‘, ‘a‘];
+:匹配+号前一个字符1次或多次,例如re.findall("ab+", "ab+cd+abb+bba"),结果为[‘ab‘, ‘abb‘];
?:匹配?号前一个字符1次或0次。注意?号可以匹配0次,不匹配的话,返回的不是None,而是‘‘;
{n}:匹配前一个字符n次;
{n,}:匹配前一个字符n次或多次;
{n, m}:匹配前一个字符n到m次,最少匹配n次,最多匹配m次。注意,如果能匹配上的字符少于n个,那就没有匹配上,返回None。例如re.findall("ab{1,3}", "abb abc abbcbbb"),结果为[‘abb‘, ‘ab‘, ‘abb‘];
③匹配的方向
^:匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a", "\nabc\neee", flags=re.MULTILINE);
\A:只从字符开头匹配,例如re.search("\Aabc", "alexabc") 是匹配不到的;
$:匹配结尾的字符,或re.search("foo$", "bfoo\nsdfsf", flags=re.MULTILINE).group()也可以;
\Z:匹配字符结尾,同$符号;
④分组匹配
(...):分组匹配,例如re.search("(abc){2}a(123|456)c", "abcabca456c").group(),结果为[‘abcabca456c‘];
(?P<name>...):分组匹配 ,例如
print(re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})", "371481199306143242").groupdict()),结果为{‘province‘: ‘3714‘, ‘city‘: ‘81‘, ‘birthday‘: ‘1993‘}
3.re模块的匹配语法
re.match(pattern, string, flags=0):从起始位置开始根据模型去字符串中匹配指定内容,匹配单个。
re.search(pattern, string, flags=0):会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。只匹配单个,是常用的匹配语法;
re.findall(pattern, string, flags=0):不止匹配单个,会匹配到字符串中所有符合条件的字符,把所有匹配到的字符放到列表中的元素,并返回;
re.sub(pattern, repl, string, count=0, flags=0):将匹配到的字符替换成指定的字符。相比于str.replace功能更加强大;repl是替换后的值。count是替换的次数,不写就代表全部替换。
re.split(pattern, string, maxsplit=0, flags=0):将匹配到的字符当做分隔符,分隔符与分隔符之间的字符当作列表元素,然后返回列表。相比于str.split更加强大;maxsplit是分割多少次,不写就代表将匹配到的全部分割。
re.splitall(pattern, string, flags=0):以匹配到的字符当做列表分隔符;
各字段详解:
如果匹配成功,则返回所匹配的字符。
如果没有匹配成功,不用group()取结果,直接通过print()打印,显示的是None。而用group()取结果会报错;
pattern是正则表达式;string是要匹配的字符串;
flags是标志位,用于控制正则表达式的匹配方式。
flags=re.I(注意,是大写的i。完成写法flags=re.IGNORECASE):忽略大小写;
flags=re.M(完整写法flags=re.MULTILINE):多行匹配模式,改变^和$的限制。从多行内容中匹配模式;
flags=re.S(完整写法flags=re.DOTALL):点匹配任意字符,包括换行;
group()和group(0):取整个正则表达式匹配的字符串,返回的结果是一个字符串;
group(1):第一个括号部分的正则表达式匹配的结果,返回的结果是一个字符串;
groups():从group(1)开始往后的所有值,组成一个元组;
groupdict():从group(1)开始往后的所有值,组成一个字典。和分组匹配搭配使用,在(?P<key>正则表达式)中<>号中的内容是返回字典中的key,正则表达式匹配出的结果是返回字典中key所对应的value。;
本文出自 “12031302” 博客,谢绝转载!
Python基础-第五天-常用模块