python的内置库(日期与时间处理、json、正则表达式re、logging)

五、内置库日期与时间处理

1、应用

1)作为日志信息的内容输出
2)计算某个功能的执行时间
3)用日期命名一个日志文件的名称
4)生成随机数(时间是不会重复的)

2、python 中处理时间的模块

1)time
2)datetime
3)calendar

3、常见的时间表示形式

1)时间戳
2)格式化的时间字符串

4、datetime 常用的类

1)datetime  (from datetime import datetime):时间日期相关
2)timedelta  (from datetime import timedelta):计算两个时间的时间差
3)timezone  (from datetime import timezone):时区相关
import datetime
# 获取当前日期和时间
now = datetime.datetime.now()

"""字符串与时间互转"""

s="2021-09-27 06:47:06"
# 将字符串 转换为datetime实例
s1=datetime.datetime.strptime(s,'%Y-%m-%d %H:%M:%S')

# 时间转成字符串
now = datetime.datetime.now()
result = now.strftime('%a, %b %d %H:%M')

"""时间戳与时间互转"""

mtimestamp = 1632725226.129461

# 将时间戳转成时间 
s = datetime.datetime.fromtimestamp(mtimestamp)

# 将时间转成时间戳
print(s.timestamp())
"""
练习:写一段代码,生成一个以时间命名的日志文件(字符串格式)。
并向日志文件中写入日志数据。
"""
# 获取当前时间,时间格式
now_time = datetime.datetime.now()
# 转换为字符串格式
now_time1 = now_time.strftime('%a%b%d_%H%M%S')
print(now_time1)

# 生成一个以时间命名的日志文件
log_name = now_time1 + '.log'
with open(log_name, 'w+', encoding='utf-8') as f:
    # 日志格式:时间datetime 空格 级别[level] 行号line:13 日志信息this is a log message
    message = f"{now_time} [info] line: 14 this is a log message"
    f.write(message)

六、内置库json

1、json

1)JSON 是用于存储和交换数据的语法,是一种轻量级的数据交换格式。
2)使用场景:接口数据传输、序列化、配置文件

2、JSON 结构

1)键值对形式
2)数组形式

{
    "language": [
        {
            "name": "python",
            "url": "https://www.python.org/"
        },
        {
            "name": "java",
            "url": "https://www.java.com/zh-CN/"
        }
    ]
}

3、Python 与 JSON 数据类型对应

image

4、json 库

1)可以从字符串或文件中解析 JSON
2)该库解析 JSON 后将其转为 Python 字典或者列表

5、常用方法

1)dumps():将 Python 对象编码成 JSON 字符串
2)loads():解码 JSON 数据,该函数返回 Python 对象
3)dump(): Python 对象编码,并将数据写入 json 文件中
4)load():从 json 文件中读取数据并解码为 Python 对象
import json

# 定义 python 结构
data = [{'a': 1, 'b': '2', 'c': True, 'd': False, 'e': None }]   

# 将 python 对象编码为 JSON 字符串
json_data = json.dumps(data)
# 将 JSON 字符串解码为 python 对象
python_data = json.loads(json_data)
# 写入 JSON 数据,在代码当前目录生成一个 data.json 的文件
with open('data.json', 'w') as f:    
     json.dump(data, f)   
# 读取数据,读取 json 文件并解码成 python 对象
with open('data.json', 'r') as f:
     data = json.load(f)

6、dumps 常用参数

1)indent:根据数据格式缩进显示,默认为 None,没有缩进
2)ensure_ascii:对中文使用 ASCII 编码,默认为 True
import json

data = {
    'a': 1, 
    'b': '霍格沃兹', 
    'c': True, 
    'd': False, 
    'e': None }

python_data = json.dumps(data, indent=4, ensure_ascii=False)
print(python_data)

七、内置库正则表达式re

1、正则表达式

1)正则表达式就是记录文本规则的代码
2)可以查找操作符合某些复杂规则的字符串

2、使用场景

1)处理字符串
2)处理日志

3、在 python 中使用正则表达式

1)把正则表达式作为模式字符串
2)正则表达式可以使用原生字符串来表示
3)原生字符串需要在字符串前方加上 r'string'
# 匹配字符串是否以 hogwarts_ 开头
r'hogwart_\w+'

4、正则表达式对象转换

1)compile():将字符串转换为正则表达式对象
2)需要多次使用这个正则表达式的场景
import re

'''
prog:正则对象,可以直接调用匹配、替换、分割的方法,不需要再传入正则表达式
pattern:正则表达式
'''

prog = re.compile(pattern)

5、匹配字符串

1)match():从字符串的开始处进行匹配
2)search():在整个字符串中搜索第一个匹配的值
3)findall():在整个字符串中搜索所有符合正则表达式的字符串,返回列表

    '''
    pattern: 正则表达式
    string: 要匹配的字符串
    flags: 可选,控制匹配方式
        - A:只进行 ASCII 匹配
        - I:不区分大小写
        - M:将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行
        - S:使用 (.) 字符匹配所有字符(包括换行符)
        - X:忽略模式字符串中未转义的空格和注释
    '''
    re.match(pattern, string, [flags])
    re.search(pattern, string, [flags])
    re.findall(pattern, string, [flags])

6、替换字符串

sub():实现字符串替换

    '''
    pattern:正则表达式
    repl:要替换的字符串
    string:要被查找替换的原始字符串
    count:可选,表示替换的最大次数,默认值为 0,表示替换所有匹配
    flags:可选,控制匹配方式
    '''
    re.sub(pattern, repl, string, [count], [flags])

7、分割字符串

split():根据正则表达式分割字符串,返回列表

    '''
    pattern:正则表达式
    string:要匹配的字符串
    maxsplit:可选,表示最大拆分次数
    flags:可选,控制匹配方式
    '''
    re.split(pattern, string, [maxsplit], [flags])
import re

# 匹配包含helloworld的字符串
pattern = r'helloworld'

# 转化为正则对象
p = re.compile(pattern)

# # 匹配以hel开头的字符串
pattern = r'he\w+'

s1 = "Hello welcome to  python"
s2 = "can you Help me, help"
# re.I不区分大小写
# match():从字符串的开始处进行匹配
matc1 = re.match(pattern, s1, re.I)
print(matc1)
print(f"匹配值的起始位置为:{matc1.start()}")
print(f"匹配值的结束位置为:{matc1.end()}")
print(f"匹配位置的元组为:{matc1.span()}")
print(f"要匹配的字符串为:{matc1.string}")
print(f"要匹配的数据为:{matc1.group()}")

match2 = re.match(pattern, s2, re.I)
print(match2)

# search():在整个字符串中搜索第一个匹配的值
sear1 = re.search(pattern, s1, re.I)
# 只要匹配到1个就返回,后面是否还有不会再返回
sear2 = re.search(pattern, s2, re.I)
print(sear1)
print(sear2)

# findall():在整个字符串中搜索所有符合正则表达式的字符串,返回列表
fin1 = re.findall(pattern, s1, re.I)
fin2 = re.findall(pattern, s2, re.I)
print(fin1)
print(fin2)

"""替换字符"""
# 匹配手机号码
pattern = r"1[34578]\d{9}"
s1 = "中奖号码 123456,联系号码 15611111111"
# 将电话号码打码
result = re.sub(pattern, '1xxxxxxxxxx', s1)
print(result)

"""分割字符串"""
a = r"[?|&]"  # 以?和&作为分隔符
url = "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=python%E5%AE%98%E7%BD%91&fenlei=256&rsv_pq=0xf4ed1f980030cb4d&rsv_t=a6a9K5n90qGD4ZUqfBqcZRVLRhGycxbnjiBXHbcJWDk%2BIckzq2wbe4jKFCz1&rqlang=en&rsv_enter=1&rsv_dl=tb&rsv_sug2=0&rsv_btype=i&inputT=3414&rsv_sug4=3414"

r = re.split(a, url)
print(r)

八、内置库pythonlogging和高级使用

1、日志作用

1)调试
2)辅助定位问题
3)数据分析

2、日志的级别

3、日志的用法

4、设置日志的级别

# 设置哪个级别就会打印哪个级别及以上级别的日志
logging.basicConfig(level=logging.INFO)

5、保存日志到文件

# 日志存放在文件example.log中
logging.basicConfig(filename='example.log', level=logging.DEBUG)

6、设置时间格式

# 显示日期/时间,默认的时间格式
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')
# 控制日期/时间格式
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

7、python 日志进阶

8、python 日志记录流程

9、python 日志定义

官网:https://docs.python.org/zh-cn/3/howto/logging.html

import logging

# 创建一个记录器,
logger = logging.getLogger('simple_example')
# 设置级别
logger.setLevel(logging.DEBUG)

# 创建一个处理器(流处理器, 输出到终端上 )
# ch = logging.StreamHandler()
# 创建一个文件处理器,存放到文件中
ch = logging.FileHandler("mylog.log", encoding="utf-8")
# 设置级别
ch.setLevel(logging.DEBUG)

# 创建一个格式器
# asctime时间,name名字,levelname级别,message消息
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 格式器放在处理器中
ch.setFormatter(formatter)

# 处理器放到记录器中
logger.addHandler(ch)

# 记录器定义不同的级别的日志
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

10、封装日志公共函数

import logging
import os

def get_logger():
    # 定义记录器
    # 打印当前文件名1
    print(os.path.basename(__file__))
    # 名字是当前的文件名os.path.basename(__file__)
    logger = logging.getLogger(os.path.basename(__file__))
    # 设置级别
    logger.setLevel(logging.DEBUG)
    # 定义文件处理器
    ch = logging.FileHandler(filename='mylog01.log', encoding="utf-8")
    # 设置级别
    ch.setLevel(logging.DEBUG)
    # 定义格式器
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    # 格式器放在处理器中
    ch.setFormatter(formatter)
    # 处理器放到记录器中
    logger.addHandler(ch)
    return logger

# 调用
logger = get_logger()


def log_info(message):
    logger.info(message)


logger.debug('debug message')
# logger.info('info message')
log_info("info message")
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

11、日志配置文件

配置文件 logging.conf
[loggers] # loggers 对象列表
        keys=root,main

[handlers] # handlers 对象列表
        keys=consoleHandlers,fileHandlers

[formatters] # formatters 列表
        keys=fmt

[logger_root]
        level=DEBUG
        handlers=consoleHandlers,fileHandlers

[logger_main] # main logger
        level = DEBUG
        handlers = fileHandlers
        qualname=main
        propagate=0

[handler_consoleHandlers]# consoleHandlers 指定控制器的输出方向、级别、输出格式、参数
        class = StreamHandler
        level = DEBUG
        formatter = fmt
        args = (sys.stdout,)

[handler_fileHandlers]# 循环日志文件 以文件大小来 分割# 每隔 1000 Byte 划分一个日志文件,备份文件为 3 个
        class = logging.handlers.RotatingFileHandler
        level = DEBUG
        formatter = fmt
        args = ('./logs/test.log', 'a', 10000, 3, 'UTF-8')

[formatter_fmt] # fmt 格式
        format=%(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
        datefmt=
# log_demo03_conf.py文件
import logging.config
# 引用配置文件
logging.config.fileConfig("logging.conf")
logger = logging.getLogger("main")  # 引用main
logger.debug("这是debug日志")