首页 > 代码库 > 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基础-第五天-常用模块