Python常用模块

 前言

在使用Python进行开发时,会经常使用到不同的模块来帮助我们完成某部分功能的实现,因此掌握一些常用模块的常用方式可以帮助我们加速程序开发。

time模块

在Python中通常有以下几种方式来表示时间:

1.时间戳(timestamp),表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,属于浮点型可以用来计算时间间隔。

>>> import time
>>> time.time()
1622362862.679771

2.格式化的时间字符串(Format String),主要用来展示时间。

>>> import time
>>> time.strftime('%Y-%m-%d %H:%M:%S %p')  # Y-年份 m-月 d-日  H- 小时 M-分钟 S-秒  p-AM/PM
'2021-05-30 16:22:44 PM'

# 上述代码可以简写,使用X表示时分秒
>>> time.strftime('%Y-%m-%d %X')
'2021-05-30 16:23:34'

3.结构化的时间(struct time)

>>> print(time.localtime()) #本地时区的struct_time
>>> print(time.gmtime())    #UTC时区的struct_time

在上述三种时间格式中,计算机能够识别的时间格式只有时间戳,而人类能够看懂的时间是格式化的时间字符串或者结构化时间,因此三者之间有转换关系。

1.时间戳--->结构化时间--->格式化时间

# 时间戳----结构化时间
import time

time1 = time.time()  # 时间戳
res = time.localtime(time1)  # 将时间戳转为结构化时间
print(res)

# 结构化时间----格式化时间
res = time.localtime()  # # 获取结构化时间
time1 = time.strftime('%Y-%m-%d %X',res)  # 讲结构化时间转为格式化时间
print(time1)

2.格式化时间--->结构化时间--->时间戳

# 格式化时间---结构化时间
res = time.strftime('%Y-%m-%d %X',res)  # 获取格式化时间
print(res)

time1 = time.strptime(res,'%Y-%m-%d %X')  # 格式化时间转成结构化时间
print(time1)

# 结构化时间转成时间戳
res = time.localtime()  # 获取结构化时间
time1 = time.mktime(res)
print(time1)

datetime模块

datetime模块可以用来加减时间

import datetime

print(datetime.datetime.now())  # 格式化输出时间
print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分

random模块

random模块可以用来生成随机数、随机验证码等功能。

import random
# 随机获取0-1之间的浮点数
print(random.random())

# 随机获取大于等于1 小于等于6之间的整形数字
print(random.randint(1,6))

# 随机获取大于等于1 小于6之间的整形数字
print(random.randrange(1,6))

# 随机获得参数中的一个数据
print(random.choice((111,'aaa',456,[1234,'qq'])))

# 指定元素个数自由组合,随机输出,当指定元素个数为1时,与choice作用相同
print(random.sample([111, 'aaa', 'ccc','ddd'],1))
print(random.sample([1,3,5,7,89,],3))

# shuffle 打乱原列表的顺序
list1 = [1,2,3,5]
random.shuffle(list1)
print(list1)

# 使用random模块生成验证码
def func(n=6):
    # 获取随机的26个大写英文字母,根据ASC码表
    al_A = chr(random.randint(65,90))
    # 获取随机的26个小写英文字母,根据ASC码表
    al_a = chr(random.randint(97,122))
    # 获取随机数字
    num = random.randint(0,9)
    # 生成随机验证码
    res = ''
    for i in range(n):
        res += random.choice([al_a,al_A,str(num)])
    return res

os模块

os模块提供了非常丰富的方法用来处理文件和目录,是一个非常大的与操作系统交互的模块,这里介绍常用的一些方法。

import os

os.listdir(path)  # 获取某一个文件夹下的所有子文件夹名称以及文件名称
os.remove(path)  # 删除指定路径的文件
os.rename("oldname","newname")  # 重命名文件/目录
os.path.dirname(__file__)  # 获取当前文件所在的文件夹
os.path.basename(__file__)  # 获取当前文件的文件名字
os.path.split(path)  # 将path分割成目录和文件名二元组返回
os.path.exists(path)  # 如果path存在,返回True;如果path不存在,返回False
os.listdir('dirname')  # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.mkdir('dirname')   # 在当前文件路径下生成单级目录
os.getcwd()  # 获取当前工作目录,即当前python脚本工作的目录路径
os.path.abspath(path)  # 返回path规范化的绝对路径
os.path.join('a','b')  # 对文件路径进行拼接

sys模块

sys.version       # 获取Python解释程序的版本信息
sys.path          # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform      # 返回操作系统平台名称

序列化与反序列化模块

json模块和pickle模块是用来序列化和反序列化数据的模块。

序列化指的是把内存的数据类型转换成一种特定的格式的内容,该格式的内容可用于存储或者传输给其他平台(其他编程语言)使用,反序列化就是将其他平台上的数据转换成python能够识别的数据格式。

序列化:
内存中的数据类型----》序列化----》特定的格式(json/pickle格式)
反序列化:
内存中的数据类型《----反序列化《----特定的格式(json/pickle格式)

数据进行序列化有两种用途:

其一,可以持久保存程序运行过程中产生的数据,将数据写到磁盘中。

其二,序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

序列化和反序列化的操作可以借助json和pickle模块。

json模块

json格式的数据是所有编程语言通用的数据类型,如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为json格式,因为json格式表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。但是json不能用于某种语言独有数据类型的序列化或者反序列化操作,比如python的集合类型。

还需要注意json格式的字符串与Python语法之间的区别,不要混淆了哟,比如json格式字符串是不支持单引号的,但是字典支持单引号哦~

import json

# 序列化操作
res = json.dumps([1,2,3,4,True,False])
print('序列化结果',res)  # 序列化结果 [1, 2, 3, 4, true, false],'true'/false---字符串类型
# 序列化结果可以存在文件中:复杂方法
with open('json.txt', 'w', encoding='utf-8') as f:
    f.write(res)

# 将序列化的结果写入文件的简单方法:
with open('json.txt', 'w', encoding='utf-8') as f:
    json.dump([1,2,3,4,True,False],f)
    
# 反序列化
res1 = json.loads(res)
print('反序列化',res1,type(res1))
# 将文件中的数据反序列化:复杂方法
with open('json.txt', 'r', encoding='utf -8') as f:
    json_res = f.read()
    res = json.loads(json_res)
    print(res)

# 反序列化的简单方法
with open('json.txt', 'r', encoding='utf -8') as f:
    res = json.load(f)
    print(res,type(res))

pickle模块

pickle模块的用法与json模块用法相同,不同的是它只能用于python。可以序列化python独有的数据类型。

import pickle
# 序列化
res = pickle.dumps({1,2,3})
# 集合属于python独有的,使用pickle可以进行序列化
print(res)
# 反序列化
res1 = pickle.loads(res)
print(res)

hashlib模块

hash是一类算法,通过接收传入的内容,经过运算后得到一串hash值,hash值有以下特点:

I 只要传入的内容一样,得到的hash值必然一样 ;

II 不能由hash值返解成内容;

III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度一定;

基于以上特点,hash可以用来进行密码的传输与校验,经常使用的加密算法是md5。

import hashlib

m = hashlib.md5()  # 相当于建造一个工厂,用来接收需要加密的数据
m.update('hello'.encode('utf-8'))  # 接收加密的数据
m.update('world'.encode('utf-8'))  # 可以多次接收加密的数据
res = m.hexdigest()   # 对需要加密的数据'helloworld'进行处理,得到加密后的结果
print(res)  # fc5e038d38a57032085441e7fe7010b0

m1 = hashlib.md5('he'.encode('utf-8'))
m1.update('llo'.encode('utf-8'))
m1.update('w'.encode('utf-8'))
m1.update('orld'.encode('utf-8'))
res = m1.hexdigest()  # # 对需要加密的数据'helloworld'进行处理,得到加密后的结果
print(res)  # fc5e038d38a57032085441e7fe7010b0

# 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样。

以上加密算法虽然不能反解,但是可以通过撞库进行反解,通过将猜测密码加密后与已知md5字符串进行比对进行反解,如下述代码:

cryptograph='aee949757a2e698417463d47acac93df'  # 已知的md5加密后的字符串
import hashlib

# 制作密码字段
passwds=[
    'asdfgh',
    'asdfh66',
    'asdfh6678'
]

dic={}
for p in passwds:
    res=hashlib.md5(p.encode('utf-8'))
    dic[p]=res.hexdigest()

# 模拟撞库得到密码
for k,v in dic.items():
    if v == cryptograph:
        print('撞库成功,明文密码是:%s' %k)
        break

因此可以对加密算法中添加自定义的key再进行加密,俗称加盐,加盐就可以提升撞库的成本。

import hashlib

m = hashlib.md5()

m.update('天王'.encode('utf-8'))
m.update('hello'.encode('utf-8'))
m.update('盖地虎'.encode('utf-8'))
m.update('world'.encode('utf-8'))
print(m.hexdigest()

logging模块

logging模块可以用来记录程序运行的日志,日志在程序开发中是非常重要的部分,在线上生产环境或者在测试环境中可以通过日志来查看程序运行是否正常,如果程序异常,可以通过日志快速定位到异常的代码位置,因此记录日志需要尽可能的详细,在python开发中可以借助logging模块记录日志。

import logging

# 数字大小代表不同等级
CRITICAL = 50 
ERROR = 40
WARNING = 30 
INFO = 20
DEBUG = 10
NOTSET = 0 


logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

默认warning及以上级别的日志(waring error critical)可以输出到终端上, 日志应该记录在文件中方便查看,可以为logging模块通过logging.basicConfig()指定全局配置,可以将日志保存到文件中。

import logging

logging.basicConfig(filename='test.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)

上述参数及其他未用到的参数介绍如下:
filename:用指定的文件名创建FiledHandler,用来打印到文件中
datefmt:指定日期时间格式。
level:根据数字设置的日志级别

format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

logging模块在使用过程中,需要用到Formatter,Handler,Logger,Filter对象

logger:产生日志的对象;

Filter:过滤日志的对象,不常用;

Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端;

Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式。

上面说了这么多,到底如何在python的项目中使用logging模块记录日志呢?在项目开发中,只需要记住下面的用法就OK了。

首先,在项目的配置文件(settings.py)中对日志格式进行配置:

# settings.py

# 日志文件
LOG_PATH = os.path.join(BASE_DIR,'log')
LOG_UER_PATH = os.path.join(LOG_PATH,'access.log')

# 定义三种日志输出格式 
standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' \
                  '%(levelname)s - %(message)s'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 日志配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    # handlers是日志的接收者,不同的handler会将日志输出到不同的位置
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            # 'maxBytes': 1024*1024*5,  # 日志大小 5M
            # 'maxBytes': 1000,
            # 'backupCount': 5,
            'filename': LOG_UER_PATH,  # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
            'encoding': 'utf-8',
            'formatter': 'standard',

        },
        #打印到文件的日志,收集info及以上的日志
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'filename': LOG_UER_PATH, # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
            'encoding': 'utf-8',
            'formatter': 'test',

        },
    },
     
    # loggers是日志的产生者,产生的日志会传递给handler然后控制输出
    'loggers': {
        # logging.getLogger(__name__)拿到的logger配置,如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key ,解决方式就是定义一个空的key,这样我们再取logger对象时logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置
        '': {
            'handlers': ['default', ],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
    },
}

然后,在其他文件中使用logging模块记录日志:

# test.py

# logging是一个包,需要使用其下的config、getLogger
from logging import config
from logging import getLogger

# 加载日志字典配置
logging.config.dictConfig(settings.LOGGING_DIC)

# 生成日志对象
logger = logging.getLogger('test')

# 记录日志
logger.info('记录一条日志')

logging模块看起来非常复杂,但是使用起来按照上面的方式,在项目开发的时候,只需要拷贝过去使用就可以了。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/384170.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Docker快速部署MySQL

部署MySQL 使用Docker安装,仅仅需要一步即可,在命令行输入下面的命令 docker run -d \--name mysql \-p 3306:3306 \-e TZAsia/Shanghai \-e MYSQL_ROOT_PASSWORD123456 \mysql MySQL安装完毕!通过任意客户端工具即可连接到MySQL. 当我们执…

代码随想录算法训练营第四十九天(动态规划篇)| 474. 一和零, 完全背包理论基础

474. 一和零 题目链接:https://leetcode.cn/problems/ones-and-zeroes/submissions/501607337/ 思路 之前的背包问题中,我们对背包的限制是容量,即每个背包装的物品的重量和不超过给定容量,这道题的限制是0和1的个数&#xff0…

微服务多级缓存

多级缓存 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后,先查询Redis,如果未命中则查询数据库,如图: 存在下面的问题: •请求要经过Tomcat处理,Tomcat的性能成为整个系统的瓶颈 •Redis缓存…

【MATLAB】GA_BP神经网络回归预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 GA_BP神经网络回归预测算法结合了遗传算法(Genetic Algorithm, GA)和BP神经网络(Backpropagation Neural Network, BPNN),用于解…

Java+springboot+MYSQL停车场管理系统的设计与实现82061-计算机毕业设计项目选题推荐(免费领源码)

摘要 由于数据库和数据仓库技术的快速发展,停车场管理系统建设越来越向模块化、智能化、自我服务和管理科学化的方向发展。停车场管理系统对处理对象和服务对象,自身的系统结构,处理能力,都将适应技术发展的要求发生重大的变化。停…

【机器学习】支持向量机(SVM)

支持向量机(SVM) 1 背景信息 分类算法回顾 决策树 样本的属性非数值 目标函数是离散的 贝叶斯学习 样本的属性可以是数值或非数值目标函数是连续的(概率) K-近邻 样本是空间(例如欧氏空间)中的点目标函…

Duilib List 控件学习

这是自带的一个示例; 一开始运行的时候List中是空的,点击Search按钮以后就填充列表框; 先看一下列表框列头是在xml文件中形成的; <List name="domainlist" bkcolor="#FFFFFFFF" ... menu="true"> <ListHeader height="24…

【Git】合并多次commit提交

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、git rebase合并二、git reset合并 前言 在开发阶段&#xff0c;由于我们会频繁的修改代码&#xff0c;会存在多次提交同一个修改&am…

酷开科技荣获“消费者服务之星”称号后的未来展望

恭喜酷开科技荣获2023年第四季度黑猫平台“消费者服务之星”称号&#xff01;这是对酷开科技长期以来坚持用户至上、用心服务的肯定和认可。作为OTT行业的佼佼者&#xff0c;酷开科技一直秉承着“以用户为中心”的服务理念&#xff0c;不断追求卓越品质&#xff0c;为用户提供更…

Microsoft Word 清除格式

Microsoft Word 清除格式 References 选择文本&#xff0c;用快捷键 Ctrl Shift N&#xff0c;可以快速清除格式。 选择文本&#xff0c;清除格式。 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

汉服租赁网站:Java技术的文化应用

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Microsoft Visio 弧线

Microsoft Visio 弧线 1. 指针工具 -> 弧线2. 弧线References 1. 指针工具 -> 弧线 2. 弧线 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

[Python进阶] 识别验证码

11.3 识别验证码 我们再开发某些项目的时候&#xff0c;如果遇到要登录某些网页&#xff0c;那么会经常遇到输入验证码的情况&#xff0c;而每次人工输入验证码的话&#xff0c;比较浪费时间。于是&#xff0c;可以通过调用某些接口进行识别。 11.3.1 调用百度文字识别接口 …

spring 入门 一

文章目录 Spring简介Spring的优势Spring的体系结构 Spring快速入门Spring程序开发步骤导入Spring开发的基本包坐标编写Dao接口和实现创建Spring核心配置文件在Spring配置文件中配置UserDaoImpl使用Spring的API获得Bean实例 Spring配置文件Bean标签基本配置Bean标签范围配置Bean…

揭秘外观模式:简化复杂系统的关键设计策略

前言 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它隐藏了系统的复杂性&#xff0c;并向客户端提供了一个可以访问系统的接口。这种类型的设计模式向现有的系统添加一个接口&#xff0c;来隐藏系统的复杂性。这种模式涉及到一个单一的类…

【Linux进程间通信】用管道实现简单的进程池、命名管道

【Linux进程间通信】用管道实现简单的进程池、命名管道 目录 【Linux进程间通信】用管道实现简单的进程池、命名管道为什么要实现进程池&#xff1f;代码实现命名管道创建一个命名管道 理解命名管道匿名管道与命名管道的区别命名管道的打开规则 作者&#xff1a;爱写代码的刚子…

《Git 简易速速上手小册》第7章:处理大型项目(2024 最新版)

文章目录 7.1 Git Large File Storage (LFS)7.1.1 基础知识讲解7.1.2 重点案例&#xff1a;在 Python 项目中使用 Git LFS 管理数据集7.1.3 拓展案例 1&#xff1a;使用 Git LFS 管理大型静态资源7.1.4 拓展案例 2&#xff1a;优化现有项目中的大文件管理 7.2 性能优化技巧7.2.…

刘知远LLM——神经网络基础

文章目录 神经网络基础基本构成如何训练&#xff1f; Word2Vec例子负采样&#xff1a; 循环神经网络 RNN门控计算单元 GRU长短时记忆网络 LSTM遗忘门输入门输出门双向RNN卷积神经网络 CNNpytorch实战 神经网络基础 基本构成 全称&#xff1a;人工神经网络。启发于生物神经细胞…

[VulnHub靶机渗透] WestWild 1.1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

全面详细对比@Resource和@Autowired

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Resource和Autowired概述 在Java的Spring框架中&#xff0c;Resource和Autowired都是用于实现依赖注入&#xff08;Dependency Injection, DI&#xff09;的重要注解。依赖…