os模块和sys模块回顾:【记】
1. os模块:
# 文件和文件夹相关的
os.listdir
os.remove
os.rename
os.mkdir
os.rmdir
os.makedirs
os.removedirs
# 和执行操作系统命令相关
os.popen/os.system
#例:
import os
os.system('dir')
ret = os.popen('dir')
print(ret.read())
# 工作目录:在哪个文件下执行的这个py文件,哪一个目录就是你的工作目录
import os
os.chdir('D:\python_22\day21')
print('-->',os.getcwd())
open('s21day21tmp','w').close()
# os.path
os.path.isfile
os.path.isdir
os.path.isexits
ps.path.basename 获取这个路径的最后一个值
# D:\python_22\day21 --> day21
# D:\python_22\day21\3.递归习题.py --> 3.递归习题.py
os.path.dirname 获取这个路径的上一级目录
# D:\python_22\day21 --> D:\python_22
# D:\python_22\day21\3.递归习题.py --> D:\python_22\day21
os.path.split(path)
# D:\python_22\day21\3.递归习题.py -->(D:\python_22\day21,3.递归习题.py)
os.path.join(dirname,basename) 跨平台的
os.path.getsize
oa.path.getmtime/getatimes
# os.walk
#举例:
import os
g = os.walk('D:\python22\day21')
for i in g :
print i #元组,元组包含三个元素:路径,路径下所有文件夹名,路径下所有文件名
import os
g = os.walk('D:\python22\day21')
for i in g :
path,dir_lst,name_lst = i #元组拆包
print(path,name_lst)
#应用:
查看一个文件夹下的所有文件,这个文件夹下面还有文件夹
计算一个文件夹下的所有文件的大小,这个文件夹下还有文件夹
2.sys模块: sys 和python解释器交互的
sys.path 模块搜索路径
sys.argv 在运行python脚本的时候写在python命令后面的是啥,打印出来的就是啥。在执行python脚本的时候 写在python 之后的所有的内容,形成了一个列表
sys.modules 查看导入了哪些模块
#应用举例:
import sys
if sys.argv[1] == 'alex' and sys.argv[2] == 'sb':
print('登录成功')
shutil模块:
import shutil
# 拷贝文件
shutil.copy2('原文件', '现文件')
shutil.copy2('file', 'temp')
#示例:
shutil.copy2('D:\python22\day21\lianjia.html', 'D:\python22\day21\lianjia_bk.html')
# 拷贝目录
shutil.copytree("原目录", "新目录", ignore=shutil.ignore_patterns("*.pyc"))
shutil.copytree("/Users/jingliyang/PycharmProjects/面试题/常用模块/logging模块", "logging模块2", ignore=shutil.ignore_patterns("__init__.py"))
#示例:
shutil.copytree("outer","outer3",ignore=shutil.ignore_patterns("__init__.py","sag")) #第三个参数可不写, *.py 表示所有py文件都不拷贝 *.mp4 表示所有mp4文件都不拷贝
# 删除目录
shutil.rmtree("temp", ignore_errors=True)
shutil.rmtree("logging模块2", ignore_errors=True)
# 移动文件/目录
shutil.move("logging模块", "logging2", copy_function=shutil.copy2)
# 获取磁盘使用空间
total, used, free = shutil.disk_usage(".")
print("当前磁盘共: %iGB, 已使用: %iGB, 剩余: %iGB"%(total / 1073741824, used / 1073741824, free / 1073741824))
# 压缩文件
shutil.make_archive('压缩文件夹的名字', 'zip','待压缩的文件夹路径')
shutil.make_archive('logging2', 'zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/随机数')
# 解压文件
shutil.unpack_archive('zip文件的路径.zip','解压到目的文件夹路径')
shutil.unpack_archive('/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/logging2.zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/tmp')
参考资料
https://docs.python.org/3/library/shutil.html
https://segmentfault.com/a/1190000016689023?utm_source=tag-newest
logging模块:
# 为什么要写log?
# log是为了排错
# log用来做数据分析的
# 购物商城 - 数据库里
# 什么时间购买了什么商品
# 把哪些商品加入购物车了
# 做数据分析的内容 - 记录到日志
# 1.一个用户什么时间在什么地点 登录了购物程序
# 2.搜索了哪些信息,所长时间被展示出来了
# 3.什么时候关闭了软件
# 4.对哪些商品点进去看了
项目中一定要写日志,写日志的用途:
1.用来记录用户的行为 - 数据分析
2.用来记录用户的行为 - 操作审计
3.排查代码中的错误
函数式简单配置:
输出内容是有等级的 : 默认处理warning级别以上的所有信息
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
import logging
logging.debug('debug message') # 调试
logging.info('info message') # 信息
logging.warning('warning message') # 警告
logging.error('error message') # 错误
logging.critical('critical message') # 批判性的
#运行结果;
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
debug信息在写程序时仍然要写,在正常运行过程中不让其写入文件或打印显示。等出现了问题,把程序重启,打开调试模式,然后把问题复现,查看日志内容。
在多个函数协同工作时,快速直接定位到出问题的函数。
#例:
def cal_mul(exp):
exp = 4*6
logging.debug('4*6 = 24')
return 24
def cal_div():
pass
def cal_add():
pass
def cal_sub(exp):
exp = 3-24
logging.debug('cal_sub :3-24 = 21')
return 21
def cal_inner_bracket(exp2):
exp2 = 3-4*6
ret = cal_mul(4*6)
exp2 = 3-24
ret = cal_sub(3-24)
logging.debug('3-4*6 = -21')
return -21
def main(exp):
exp =(1+2*(3-4*6))/5
ret = cal_inner_bracket(3-4*6)
return ret
logging.basicConfig(level=logging.DEBUG) #设置参数,通过level设置等级为DEBBUG
ret = main('(1+2*(3-4))/5')
print(ret)
结果:
# DEBUG:root:4*6 = 24
# DEBUG:root:cal_sub :3-24 = 21
# DEBUG:root:3-4*6 = -21
无论你希望日志里打印哪些内容,都得你自己写,没有自动生成日志这种事儿。在你觉着可能出问题的地方 或者在排错时可能会用到的地方写一个日志 【记】
日志的格式:通过logging.basicConfig设置,来灵活配置日志级别,日志格式,输出位置:
1.输出到屏幕:
import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p')
# asctime表示时间,字符串形式的当前时间;name表示哪个用户启动的程序,Logger的名字;levelname表示日志等级,lineno调用日志输出函数的语句所在的代码行文本形式的日志级别,module表示调用日志输出函数的模块名,message表示你要打印的信息,用户输出的消息。datefmt描述时间能使用的格式
logging.warning('warning message test2')
logging.error('error message test2')
logging.critical('critical message test2')
#结果:
2019-05-29 23:44:01 PM - root - WARNING[line :56]-tt21: warning message test2
2019-05-29 23:44:01 PM - root - ERROR[line :57]-tt21: error message test2
2019-05-29 23:44:01 PM - root - CRITICAL[line :58]-tt21: critical message test2
2.输出到文件,并且设置信息的等级: 一般情况下,文件以 .log结尾
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',filename='tmp.log',level= logging.DEBUG)
logging.debug('debug 信息错误 test2')
logging.info('info 信息错误 test2')
logging.warning('warning message test2')
logging.error('error message test2')
logging.critical('critical message test2')
# 写入到了文件中,但是有乱码。向文件中写入内容是默认是追加模式,前面的内容不会清空
# debug和info等级的信息没有写入,设置级别后就可以。level= logging.DEBUG
3. 同时向文件和屏幕上输出 ,并解决乱码问题 【记】【重点】
fh = logging.FileHandler('tmp.log',encoding='utf-8') #FileHandler操作文件的操作符,()内放入日志文件名,编码方式;对应变量放入handlers=[fh,sh]
# fh2 = logging.FileHandler('tmp2.log',encoding='utf-8') #同样的日志内容可以输出到多个不同的文件中,对应变量放入handlers=[fh,sh,fh2](了解)
sh = logging.StreamHandler() #StreamHandler屏幕操作符,不用加参数,对应变量放入handlers=[fh,sh]
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level= logging.DEBUG, #一般没有问题不会调到DEBUG模式
# handlers=[fh,sh,fh2]
handlers=[fh,sh]
)#handlers=[fh,sh]放文件操作符和屏幕操作符
logging.debug('debug 信息错误 test2')
logging.info('info 信息错误 test2')
logging.warning('warning message test2')
logging.error('error message test2')
logging.critical('critical message test2')
#结果:
# 2019-05-30 00:05:34 AM - root - DEBUG[line :88]-tt21: debug 信息错误 test2
# 2019-05-30 00:05:34 AM - root - INFO[line :89]-tt21: info 信息错误 test2
# 2019-05-30 00:05:34 AM - root - WARNING[line :90]-tt21: warning message test2
# 2019-05-30 00:05:34 AM - root - ERROR[line :91]-tt21: error message test2
# 2019-05-30 00:05:34 AM - root - CRITICAL[line :92]-tt21: critical message test2
4.做日志的切分(日志切割):每隔一段时间形成一个文件,切分出来。(项目中一般用此来写日志,平时可用上面的方式)【记】
import time
import logging
from logging import handlers
sh = logging.StreamHandler() #输出到屏幕
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5) # 按照大小做切割,如按1kb切割,每次切割1kb,放入myapp.log里,设置最多切5个文件,只保留最近的5个,避免磁盘满了
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8') #按时间切,放入x2.log里,如when按照秒来切,每5秒切一个。默认按小时切。
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level= logging.DEBUG,
# handlers=[fh,sh,fh2]
handlers=[fh,rh,sh]
)
for i in range(1,100000): #每秒钟写一个信息,总共写10万个
time.sleep(1)
logging.error('KeyboardInterrupt error %s'%str(i))
配置参数:
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用户输出的消息