包的使用

包的使用#

什么是包#

Copy
# 官方解释 Packages are a way of structuring Python’s module namespace by using “dotted module names” 包是一种通过使用‘.模块名’来组织python模块名称空间的方式。 # 具体的:包是一系列模块的结合体,表示形式就是一个文件夹 该文件内部通常会有一个__init__.py文件,包的本质还是一个模块。 #需要强调的是:   1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错   2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块
  • 为何要使用包
Copy
包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来 随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性
  • 导入包的执行流程
Copy
# 首次导入包 先产生一个执行文件的名称空间 1. 创建包下面的__init__.py文件的名称空间 2. 执行包下面的__init__.py文件中的代码,将产生的名字放入包下面的__init__.py文件名称空间中 3. 在执行文件中拿到一个指向包下面的__init__.py文件名称空间的名字
  • 注意:
Copy
当作为包的设计者来说: 1. 当模块的功能特别多的情况下 应该分文件管理 2. 每个模块之间为了避免后期模块改名问题 可以使用相对导入(包里面的文件都应该是被导入的模块) 站在包的开发者来说 如果使用绝对路径来管理自己的模块 那么它只需要永远以包的路径为基准一次导入模块 站在包的使用者来说 必须将包所在的文件夹路径添加至系统环境变量中

logging模块#

  • 日志级别
Copy
import logging logging.debug('debug日志') logging.info('info日志') logging.warning('warning日志') logging.error('error日志') logging.critical('critical日志') 默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING (日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
  • 日志对象
Copy
1. logger对象:负责产生日志 2. filter对象:过滤日志 3. handler对象:控制日志输出的位置 4. formater对象:规定日志内容的格式

灵活配置日志级别,日志格式,输出位置:

Copy
import logging file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler,], level=logging.ERROR ) logging.error('你好')

日志切割

Copy
import time import logging from logging import handlers sh = logging.StreamHandler() rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5) fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8') logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[fh,sh,rh], level=logging.ERROR ) for i in range(1,100000): time.sleep(1) logging.error('KeyboardInterrupt error %s'%str(i))

配置参数

Copy
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 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 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息

logger对象配置

Copy
import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log',encoding='utf-8') # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.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')

hashlib模块#

  • 算法介绍
Copy
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。 什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。 摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。 摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。 我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值: import hashlib md5 = hashlib.md5() # 生成一个帮助造密文的对象 md5.update('how to use md5 in python hashlib?') # 往对象里面传明文数据 update只能接受bytes类型的数据 print md5.hexdigest() # 获取明文数据对应的密文 计算结果如下: 5d41402abc4b2a76b9719d911017c592 MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似: import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in ') sha1.update('python hashlib?') print sha1.hexdigest() SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长
  • 应用场景
Copy
# hashlib模块应用场景 1.密码的密文存储 2.效验文件内容是否一致
  • 加盐处理

    由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”

Copy
def get_md5(data): # 封装成函数方便下次调用 md = hashlib.md5() # 使用md5的加密方式 md.update('自己加的盐'.encode('utf-8')) # 将对象中传入自己加的盐 md.update(data.encode('utf-8')) # 将函数中传参传入对象中 return md.hexdigest() # 获取明文数据对应的密文 password = input('清输出你需要加密的值>>>:') res = get_md5(password) # 将变量传入函数中直接调用 print(res) # 打印加密结果

openpyxl模块#

  • 使用模块写文件
Copy
# openpyxl 比较火的操作excel的模块 """ excel 03版本前后缀名叫 xlx excel 03版本后后缀名叫 xlsx xlwd 写excel xlrt 读excel xlwd和xlrt既支持03版本之前的excel文件也支持03版本之后的excel文件 openpyxl 只支持03版本会后的xlsx """ from openpyxl import Workbook wb = Workbook # 生成一个工作簿 wb1 = wb.create_sheet('index',0) # 创建表index表单页,控制表单位置 wb2 = wb.create_sheet('index1',2) # 创建表index1表单页,控制表单位置 wb1.title = 'login' # 修改表单页的名称为login wb1.cell(row=6,column=3,value=888888) # 在表单index的第六行第三列添加内容888 # wb1['A3'] = 666 # 在表单index的A3位置写入内容666 # wb1['A4'] = 444 # 在表单index的A4位置写入内容444 # wb1['A5'] = '=sum(A3:A4)' # 在表单A5位置对A3和A4进行求和 wb1.append(['username','age','hobby']) # 添加表头 wb1.append(['jason',18,'study']) # 对应表头添加内容 wb1.append(['tank',11,'read']) # 对应表头添加内容 wb1.append(['agon',22,'女教练']) # 对应表头添加内容 wb.save('test,xlsx') # 保存工作簿起名为test
  • 读文件
Copy
from openpyxl import load_workbook # 读文件 wb = load_workbook('test.xlsx',read_only=True,data_only=True) # data_only表示只读数据,不读公式 print(wb.sheetnames) # 打印表单页名称 print(wb['login']['A3'].value) # 查看表单页login A3位置对应的值 print(wb['login']['A5'].value) # 查看表单页login A3位置对应的值 res = wb['login'] ge1 = res.rows for i in ge1: for j in i: print(j.value)

copy模块#

Copy
import copy # l = [1,3,[1,2]] # l1 = copy.copy(l) # 拷贝一份,浅拷贝 # print(id(l),id(l1)) # 2123774630408 2123774630472 拷贝出来的文件与源文件di并不一致 # # l[0] = 222 # 仅针对l的索引0修改数据 # # print(l,l1) # [222, 3, [1, 2]] [1, 3, [1, 2]] # l[2].append(666) # # print(l,l1) # [1, 3, [1, 2, 666]] [1, 3, [1, 2, 666]] # 浅拷贝说明: #仅仅是拷贝了一份和源文件同样的数据,但是实则上指向的内容还是和源文件一致,针对源文件进行修改,如上例,如修改源文件,针对不可变类型,源文件会断掉指向内容的值重新指向,而可变类型 l = [1,2,[1,2]] l1 = copy.deepcopy(l) l[2].append(666) print(l,l1) # [1, 2, [1, 2, 666]] [1, 2, [1, 2]] 深拷贝,源文件新增,新文件并不修改 # 深拷贝说明: #拷贝和源文件一样的数据,但是和浅拷贝不一样之处在于,深拷贝对于可变类型会新建内容,再将内容进行指向,这样对于源文件的可变类型修改,并不会改变新文件 #对于可变不可变到底是指向原来的内容,还是新建内容
posted @   元气少女郭德纲!!  阅读(90)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
CONTENTS