模块的导入和__name__
属性
-
__name__
属性:
① 当模块(.py文件称为一个模块)以脚本方式运行的时候,该模块的__name__
属性是__main__
② 当模块以模块方式被导入时,__name__
就是本模块的名字
针对上面的特性,可以在模块最后加上判断if __name__ == '__main__'
,判断当前模块是否需要执行,可以在开发过程中调试,被引用的时候就不执行。 -
模块的导入:
导入一个模块通常分三步
① 查看内存中是否有该模块,如果已经导入的模块会存储在内存中,并且会执行xxx模块中所有的可执行代码
② 查看内置路径,一般都在安装Python的路径 Lib下
③ sys.path路径中查找,是一个列表,如果模块路径找不到,就无法导入,解决问题的办法就是在sys.path中append模块路径
注:如果上面都找不到,就报错 -
绝对路径导入和相对路径导入:
① 绝对路径导入:
import xxx:导入一个模块的所有成员
import aaa,bbb:一次性导入多个模块的成员。不推荐这种写法,分开写。
from xxx import a:从某个模块中导入指定的成员。
from xxx import a,b,c:从某个模块中导入多个成员。
from xxx import *:从模块中导入所有成员。-
import xxx 和 from xxx import * 的区别:
第一种方式在使用其中成员时,必须使用模块名作为前缀。不容易产生命名冲突。
第二种方式在使用其中成员时,不用使用模块名作为前缀,直接使用成员名即可。但是容易产生命名冲突。在后定义的成员生效(把前面的覆盖了。)如何避免冲突:给模块取别名
from xxx import age as a
如何避免from xxx import *
时候将不愿意暴露的成员暴露,可以在模块中增加__all__
,该列表表示可以被外界使用的成员,例如在模块xxx中,添加__all__ = [a, b]
,外界引用的成员只有a和b,__all__
也仅对from xxx import *
有效
② 相对路径导入:
格式:from 相对路径 import xxx
相对路径:包含了点号的一个相对路径。
. 表示的是当前的路径。
..表示的是父路径。
...表示的是父路径的父路径。
依次类推。。。 -
常用模块
random
time
datetime
os sys
json:
用于网络传输序列化(dumps)和反序列化(loads),不包含btye类型
pickle:
用于网络传输序列化(dumps)和反序列化(loads),和json的区别是,他只适用于python语言中,包含byte类型,并且是直接将对象转化成byte类型,json多了一步先转成特殊的字符串
hashlib:
# 普通加密
import hashlib
data = "你好"
data1 = "小白"
ret = hashlib.md5() #创建一个加密的对象
ret.update(data.encode('utf-8')) # 加密的对象必须转成byte类型,也可以多个update
ret.update(data1.encode('utf-8'))
ret.hexdigest() # 接收加密结果
#加盐 因为目前MD5已经可以被撞库破解,需要更复杂点加密
# 固定加盐
ret1 = hashlib.md5("加盐".encode('utf-8')) #创建一个加密的对象,“加盐”可以是任意一个秘钥
ret1.update(data.encode('utf-8'))
ret1.hexdigest() # 接收加密结果
# 动态加盐
ret2 = hashlib.md5("123456"[0:2].encode('utf-8')) # 可以通过切片等方式加盐
ret2.update(data.encode('utf-8'))
ret2.update(data1.encode('utf-8'))
ret2.hexdigest() # 接收加密结果
# sha系列 金融类,安全类.用这个级别.
# 随着sha系列数字越高,加密越复杂,越不易破解,但是耗时越长.
ret3 = hashlib.sha256()
ret3.update(data.encode('utf-8'))
ret3.update(data1.encode('utf-8'))
ret3.hexdigest() # 接收加密结果
#校验文件的完整性
def file_md5(path):
ret = hashlib.sha256()
with open(path,mode='rb') as f1: # 必须以byte类型读取文件
b1 = f1.read()
# print(b1)
ret.update(b1)
return ret.hexdigest()
result = file_md5('pycharm-professional-2019.1.2.exe')
print(result)
collections
re: 详见19
shutil
shutil是一个强大的python处理文件的库
① 复制:shutil.copy("源文件","目标文件")
② 复制2:shutil.copy2("源文件","目标文件")
区别是 copy2复制后的结果保留了原来的所有信息(包括状态信息)
③ shutil.copytree("源目录", "目标目录", ignore=shutil.ignore_patterns("init.py","sag"))
ignore 是忽略文件夹中的一些文件,可以不传
④ 删除文件夹及文件:shutil.rmtree("目标目录")
(删除文件用 os.unlink(path))
⑤ 移动文件:shutil.move("源文件", "目标目录", copy_function=shutil.copy2)
⑥ 查看磁盘使用空间:
total, used, free = shutil.disk_usage("c:\")
print("当前磁盘共: %iGB, 已使用: %iGB, 剩余: %iGB"%(total / 1073741824, used / 1073741824, free / 1073741824))
⑦ 压缩文件:
shutil.make_archive('压缩后文件的名字', "zip", "源文件")
⑧ 解压缩文件:
shutil.unpack_archive("压缩文件","解压后的路径")
logging
主要掌握4个知识点
① logging模块基本的配置
② 同时在屏幕和文件上输出,并解决乱码问题
③ 日志的切割
④ pythonjsonlogger 模块
import logging
# 第一种配置方法 config配置
fh = logging.FileHandler('tmp.log', encoding='utf-8') # 往文件写
sh = logging.StreamHandler() # 屏幕输出
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers = [fh, sh]
)
# 输出内容是有等级的 : 默认处理warning级别以上的所有信息
logging.debug('debug message') # 调试
logging.info('info message') # 信息
logging.warning('warning message') # 警告
logging.error('error message') # 错误
logging.critical('critical message') # 批判性的
# 第二种配置方法 logger对象配置
logger = logging.getLogger() # 创建logger对象
logger.setLevel(logging.DEBUG)
fm = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(fm)
sh.setFormatte(fm)
logger.addHandler(fh)
logger.addHandler(sh)
logger.critical('日志信息')
日志切割与删除就是为了防止文件过大,占用计算机内存
*按天分割日志
import logging
import logging.handlers
import os
import time
# 如果日志文件夹不存在,则创建
log_dir = "log-day" # 日志存放文件夹名称
log_path = os.getcwd() + os.sep + log_dir
if not os.path.isdir(log_path):
os.makedirs(log_path)
# logging初始化工作
logging.basicConfig()
# myapp的初始化工作
myapp = logging.getLogger('myapp')
myapp.setLevel(logging.INFO)
# 添加TimedRotatingFileHandler
# 定义一个1天换一次log文件的handler
# 保留3个旧log文件
timefilehandler = logging.handlers.TimedRotatingFileHandler(
log_dir + os.sep + "sec.log",
when='D',
interval=1,
backupCount=3
)
# 设置后缀名称,跟strftime的格式一样
timefilehandler.suffix = "%Y-%m-%d_%H-%M-%S.log"
# timefilehandler.suffix = "%Y-%m-%d.log"
formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
timefilehandler.setFormatter(formatter)
myapp.addHandler(timefilehandler)
while True:
time.sleep(6)
myapp.info("test")
*按照时间回滚(就是按时间分割日志,并且限制日志文件的个数,删除早期的日志)
import time
import logging
import logging.handlers
# logging初始化工作
logging.basicConfig()
# myapp的初始化工作
myapp = logging.getLogger('myapp')
myapp.setLevel(logging.INFO)
# 添加TimedRotatingFileHandler
# 定义一个1秒换一次log文件的handler
# 保留3个旧log文件
timefilehandler = logging.handlers.TimedRotatingFileHandler("log1/myapp.log", when='S', interval=1, backupCount=3)
# 设置后缀名称,跟strftime的格式一样
timefilehandler.suffix = "%Y-%m-%d_%H-%M-%S.log"
formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
timefilehandler.setFormatter(formatter)
myapp.addHandler(timefilehandler)
while True:
time.sleep(0.1)
myapp.info("test")
#注意:filehanlder.suffix的格式必须这么写,才能自动删除旧文件,如果设定是天,就必须写成“%Y-%m-%d.log”,写成其他格式会导致删除旧文件不生效。这个配置在源码里能看出来,但是在官方文档并没有说明这一点!!!!!!!!!!
TimedRotatingFileHandler的构造函数定义如下:
TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]])
filename 是输出日志文件名的前缀,比如log/myapp.log
when 是一个字符串的定义如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
interval 是指等待多少个单位when的时间后,Logger会自动重建文件,当然,这个文件的创建
取决于filename+suffix,若这个文件跟之前的文件有重名,则会自动覆盖掉以前的文件,所以
有些情况suffix要定义的不能因为when而重复。
backupCount 是保留日志个数。默认的0是不会自动删除掉日志。若设3,则在文件的创建过程中
库会判断是否有超过这个3,若超过,则会从最先创建的开始删除。
*按照大小回滚
RotatingFileHandler基于文件大小切分
这个配置是可以生效的,符合预期
import time
# import logging
import logging.handlers
# logging初始化工作
logging.basicConfig()
# myapp的初始化工作
myapp = logging.getLogger('myapp')
myapp.setLevel(logging.INFO)
# 写入文件,如果文件超过100个Bytes,仅保留5个文件。
handler = logging.handlers.RotatingFileHandler(
'logs/myapp.log', maxBytes=500, backupCount=5)
formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
# 设置后缀名称,跟strftime的格式一样
myapp.addHandler(handler)
while True:
time.sleep(0.1)
myapp.info("file test")
pythonjsonlogger模块以json格式输出日志
import logging
from pythonjsonlogger import jsonlogger
logger = logging.getLogger()
ch = logging.StreamHandler()
ch.setFormatter(jsonlogger.JsonFormatter())
logger.setLevel(logging.INFO) # 默认是warning
logger.addHandler(ch)
logger.info({"special": "value", "run": 12})
logger.info("classic message", extra={"special": "value", "run": 12})
logger.info("asda%s", 123)
'''
{"message": null, "special": "value", "run": 12}
{"message": "classic message", "special": "value", "run": 12}
{"message": "asda123"}
网友评论