Python学习 12day__高级语法
log模块
logging 模块提供模块级别的函数记录日志
日志相关概念
- 日志
- 日志的级别(level)
- 不同的用户关注不同的程序信息
- DEBUG
- INFO
- NOTICE
- ERROR
- CRITTCAL
- ALERT
- EMERGENCY
- LOG的作用
- 调试
- 了解软件的运行情况
- 分析定位问题
- 日志信息
- time
- 地点
- level
- 内容
logging模块
- 模块中的自定义级别
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
- 初始化/写日志实例需要指定级别,只有当级别等于或高于制定级别才被记录
- 使用方式
- 直接使用logging(封装了其他组件)
- logging四大组件直接定制
logging模块级别的日志
- 使用一下几个函数
- logging.debug(msg, *args, **kwargs) 创建一条严重级别为DEBUG的日志记录
- logging.info(msg, *args, **kwargs) 创建一条严重级别为INFO的日志记录
- logging.warning(msg, *args, **kwargs) 创建一条严重级别为WARNING的日志记录
- logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录
- logging.critical(msg, *args, **kwargs) 创建一条严重级别为CRITICAL的日志记录
- logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录
- logging.basicConfig(**kwargs) 对root logger进行一次性配置
logging.basicConfig(**kwargs)
- 只在第一次调用的时候起作用
- 参数format有默认参数名
- 不配置logger则使用默认值
- 默认输出 sys.stderr
- 默认级别 WARNING
- 默认格式 level:log_name:content
1 import logging 2 LOG_FORMAT = "%(asctime)s=====%(levelname)s++++++%(message)s" # 自定义格式 3 logging.basicConfig(filename="rz.log", level=logging.DEBUG, format=LOG_FORMAT) # 没有自定义,则默认不显示warning级别一下的日志 4 logging.debug("This is a debug log") 5 logging.info("This is a info log") 6 logging.warning("This is a warning log") 7 logging.error("This is a error log") 8 logging.critical("This is a critical log")
logging模块的处理流程
- 四大组件
- 日志器(Logger):产生日志的一个接口
- 处理器(Handler):把产生的日志发送到相应的目的地
- 过滤器(Filter):更精细的控制日志的输出
- 格式器(Formatter):对输出信息进行格式化
多线程 多进程
程序:一堆代码以文本形式存入一个文档
进程:代码运行的状态
包含地址空间,内存,数据栈
每个进程有自己完全独立的运行环境,多进程共享数据是个问题
线程:一个进程的独立运行片段每一个进程可以有多个线程
轻量化的进程
一个进程的多个线程间共享数据和上下文运行环境
共享互斥问题
全局解释器锁(GIL)
Python代码的执行是由python虚拟机进行控制
在主循环中只能够有一个控制线程在执行
Python中的有关包
thread: 有问题,不好用,py3改成了_thread
threading:通行的包
1 ''' 2 利用time函数生成两个函数 3 顺序调用、 4 计算总的运行时间 5 ''' 6 7 import time 8 import _thread 9 def loop1(): 10 # ctime 得到当前时间 11 print('Start loop 1 at : ', time.ctime()) 12 # 睡眠时间 单位毫秒 13 time.sleep(4) 14 print('End loop 1 at :', time.ctime()) 15 16 def loop2(): 17 print("Start loop 2 at :", time.ctime()) 18 time.sleep(2) 19 print('End loop 2 at :', time.ctime()) 20 21 def main(): 22 print("Starting at :", time.ctime()) 23 # 启动多线程的意思是用多线程去执行某个函数 24 # 启动多线程函数为start_new_thead 25 # 参数两个,一个是需要运行的函数名,第二个是函数的参数作为元组使用,为空则使用空元组 26 # 注意:如果函数只有一个参数,需要参数后有一个逗号 27 _thread.start_new_thread(loop1, ()) 28 _thread.start_new_thread(loop2, ()) 29 print("All done at", time.ctime()) 30 if __name__ == '__main__': 31 main()
threading的使用
直接利用threading.Thread生成Thread实例
1.t = threading.Thread(target=...., args=(...,))
2.t.start()启动多线程
3.t.join() 等待多线程执行完成
1 import time 2 import threading 3 def loop1(in1): 4 # ctime 得到当前时间 5 print('Start loop 1 at : ', time.ctime()) 6 print("我是参数", in1) 7 # 睡眠时间 单位毫秒 8 time.sleep(4) 9 print('End loop 1 at :', time.ctime()) 10 11 def loop2(in1, in2): 12 print("Start loop 2 at :", time.ctime()) 13 print("我是参数", in1, "和参数", in2) 14 time.sleep(2) 15 16 print('End loop 2 at :', time.ctime()) 17 ''' 18 主线程执行完自己的任务以后,就退出了, 19 此时子线程会继续执行自己的任务,直到自己的任务结束 20 ''' 21 def main(): 22 print("Starting at :", time.ctime()) 23 # 生成treading.Thread实例 24 t1 = threading.Thread(target=loop1, args=("老王",)) 25 t1.start() 26 t2 = threading.Thread(target=loop2, args=("老张", "老李")) 27 t2.start() 28 29 print("All done at", time.ctime()) 30 if __name__ == '__main__': 31 main() 32 33 34 '''join所完成的工作就是线程同步,即主线程任务结束之后, 35 进入阻塞状态,一直等待其他的子线程执行结束之后,主线程在终止 36 ''' 37 import time 38 import threading 39 def loop1(in1): 40 # ctime 得到当前时间 41 print('Start loop 1 at : ', time.ctime()) 42 print("我是参数", in1) 43 # 睡眠时间 单位毫秒 44 time.sleep(4) 45 print('End loop 1 at :', time.ctime()) 46 47 def loop2(in1, in2): 48 print("Start loop 2 at :", time.ctime()) 49 print("我是参数", in1, "和参数", in2) 50 time.sleep(2) 51 52 print('End loop 2 at :', time.ctime()) 53 54 def main(): 55 print("Starting at :", time.ctime()) 56 # 生成treading.Thread实例 57 t1 = threading.Thread(target=loop1, args=("老王",)) 58 t1.start() 59 t2 = threading.Thread(target=loop2, args=("老张", "老李")) 60 t2.start() 61 t1.join() # 加入join 62 t2.join() # 加入join 63 print("All done at", time.ctime()) 64 if __name__ == '__main__': 65 main()
守护线程 daemon
如果在程序中,将子线程设置为守护线程,则子线程会在主线程结束的时候退出
一般认为守护线程不重要或者不能离开子线程单独执行的时候使用
1 ''' 2 子线程t1设置为守护线程,由于主线程比子线程结束早,导致子线程没有输出最后一句就被终止了 3 ''' 4 import time 5 import threading 6 7 def fun(): 8 print("Start fun") 9 time.sleep(2) 10 print("End fun") 11 12 print("Main thread") 13 14 t1 = threading.Thread(target=fun, args=()) 15 t1.setDaemon(True) # 将子线程设置为守护线程, 16 t1.start() 17 18 time.sleep(1) 19 print("Main thread end")
线程的常用属性
threading.currentThread: 返回当前线程变量
threading.enumerate: 返回一个包含正在运行的线程list
threading.activeCount: 返回正在运行的线程数量
thr.setName: 给线程设置名字
thr.getName: 得到线程的名字
1 import time 2 import threading 3 def loop1(): 4 print('Start loop 1 at : ', time.ctime()) 5 time.sleep(4) 6 print('End loop 1 at :', time.ctime()) 7 8 def loop2(): 9 print("Start loop 2 at :", time.ctime()) 10 time.sleep(2) 11 print('End loop 2 at :', time.ctime()) 12 13 def loop3(): 14 print("Start loop 3 at :",time.ctime()) 15 time.sleep(5) 16 print("End loop 3 at :", time.ctime()) 17 18 19 def main(): 20 print("Starting at :", time.ctime()) 21 # 生成treading.Thread实例 22 t1 = threading.Thread(target=loop1, args=( )) 23 t1.setName("THR_1") # 给线程设置名字 24 t1.start() 25 t2 = threading.Thread(target=loop2, args=( )) 26 t2.setName("THR_2") # 给线程设置名字 27 t2.start() 28 t3 = threading.Thread(target=loop3, args=( )) 29 t3.setName("THR_3") # 给线程设置名字 30 t3.start() 31 32 # 预期三秒后,thread2已经自动结束 33 time.sleep(3) 34 # enumerate 得到正在运行子线程,即子线程1和子线程3 35 for thr in threading.enumerate(): 36 print("正在运行的线程名字是: {0}".format(thr.getName())) 37 38 print("正在运行的子线程数量为: {0}".format(threading.activeCount())) 39 print("All done at", time.ctime()) 40 if __name__ == '__main__': 41 main() 42 # 一定要有while语句 43 # 因为启动多线程后本程序就作为主程序存在 44 # 如果主线程执行完毕,则子线程可能也需要终止 45 while True: 46 time.sleep(10)