python常用模块整理(超详细)
发布日期:2021-07-27 04:45:14 浏览次数:5 分类:技术文章

本文共 31408 字,大约阅读时间需要 104 分钟。

文章目录

OS 模块

#os模块就是对操作系统进行操作,使用该模块必须先导入模块:import osos.remove() 删除文件 os.unlink() 删除文件 os.rename() 重命名文件 os.listdir() 列出指定目录下所有文件 os.chdir() 改变当前工作目录os.getcwd() 获取当前文件路径os.mkdir() 新建目录os.rmdir() 删除空目录(删除非空目录, 使用shutil.rmtree())os.makedirs() 创建多级目录os.removedirs() 删除多级目录os.stat(file) 获取文件属性os.chmod(file) 修改文件权限os.utime(file) 修改文件时间戳os.name(file) 获取操作系统标识os.system() 执行操作系统命令os.execvp() 启动一个新进程os.fork() 获取父进程ID,在子进程返回中返回0os.execvp() 执行外部程序脚本(Uinx)os.spawn() 执行外部程序脚本(Windows)os.access(path, mode) 判断文件权限(详细参考cnblogs)os.exit() 退出终端的命令os.getenv('PATH') 获取系统的环境变量os.putenv() 将一个目录添加到环境变量中(临时增加仅对当前脚本有效)#os.path子模块:os.path.split(filename) 将文件路径和文件名分割(会将最后一个目录作为文件名而分离)os.path.splitext(filename) 将文件路径和文件扩展名分割成一个元组os.path.dirname(filename) 返回文件路径的目录部分os.path.basename(filename) 返回文件路径的文件名部分os.path.join(dirname,basename) 将文件路径和文件名凑成完整文件路径os.path.abspath(name) 将相对路径转化为绝对路径os.path.splitunc(path) 把路径分割为挂载点和文件名os.path.normpath(path) 规范path字符串形式os.path.exists() 判断文件或目录是否存在os.path.isabs() 如果path是绝对路径,返回Trueos.path.realpath(path) 返回path的真实路径os.path.relpath(path[, start]) 从start开始计算相对路径 os.path.normcase(path) 转换path的大小写和斜杠os.path.isdir() 判断name是不是一个目录,name不是目录就返回falseos.path.isfile() 判断name是不是一个文件,不存在返回falseos.path.islink() 判断文件是否连接文件,返回booleanos.path.ismount() 指定路径是否存在且为一个挂载点,返回booleanos.path.samefile() 是否相同路径的文件,返回booleanos.path.getatime() 返回最近访问时间 浮点型os.path.getmtime() 返回上一次修改时间 浮点型os.path.getctime() 返回文件创建时间 浮点型os.path.getsize() 返回文件大小 字节单位os.path.commonprefix(list) 返回list(多个路径)中,所有path共有的最长的路径os.path.lexists 路径存在则返回True,路径损坏也返回Trueos.path.expanduser(path) 把path中包含的”~”和”~user”转换成用户目录os.path.expandvars(path) 根据环境变量的值替换path中包含的”$name”和”${
name}”os.path.sameopenfile(fp1, fp2) 判断fp1和fp2是否指向同一文件os.path.samestat(stat1, stat2) 判断stat tuple stat1和stat2是否指向同一个文件os.path.splitdrive(path) 一般用在windows下,返回驱动器名和路径组成的元组os.path.walk(path, visit, arg) 遍历path,给每个path执行一个函数详细见手册os.path.supports_unicode_filenames() 设置是否支持unicode路径名

sys 模块

sys.argv 命令行参数List,第一个元素是程序本身路径sys.modules.keys() 返回所有已经导入的模块列表sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息sys.exit(n) 退出程序,正常退出时exit(0)sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0sys.version 获取Python解释程序的版本信息sys.maxint 最大的Int值sys.maxunicode 最大的Unicode值sys.modules 返回系统导入的模块字段,key是模块名,value是模块sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值sys.platform 返回操作系统平台名称sys.stdout 标准输出sys.stdin 标准输入sys.stderr 错误输出sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息sys.exec_prefix 返回平台独立的python文件安装的位置sys.byteorder 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'sys.copyright 记录python版权相关的东西sys.api_version 解释器的C的API版本sys.stdin,sys.stdout,sys.stderrstdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们我们常用print和raw_input来进行输入和打印,那么print 和 raw_input是如何与标准输入/输出流建立关系的呢?其实Python程序的标准输入/输出/出错流定义在sys模块中,分别 为: sys.stdin,sys.stdout, sys.stderr下列的程序也可以用来输入和输出是一样的:import syssys.stdout.write('HelloWorld!')print 'Please enter yourname:',name=sys.stdin.readline()[:-1]print 'Hi, %s!' % name那么sys.stdin, sys.stdout, stderr到底是什么呢?我们在Python运行环境中输入以下代码:import sysfor f in (sys.stdin,sys.stdout, sys.stderr): print f输出为:
', mode 'r' at 892210>
', mode 'w' at 892270>
', mode 'w at 8922d0>由此可以看出stdin, stdout, stderr在Python中无非都是文件属性的对象,他们在Python启动时自动与Shell 环境中的标准输入,输出,出错关联。而Python程序的在Shell中的I/O重定向与本文开始时举的DOS命令的重定向完全相同,其实这种重定向是由Shell来提供的,与Python 本身并无关系。那么我们是否可以在Python程序内部将stdin,stdout,stderr读写操作重定向到一个内部对象呢?答案是肯定的。Python提供了一个StringIO模块来完成这个设想,比如:from StringIO import StringIOimport sysbuff =StringIO()temp =sys.stdout #保存标准I/O流sys.stdout =buff #将标准I/O流重定向到buff对象print 42, 'hello', 0.001sys.stdout=temp #恢复标准I/O流print buff.getvalue()

time模块

time模块中时间表现的格式主要有三种:

a、timestamp时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量

b、struct_time时间元组,共有九个元素组。
c、format time 格式化时间,已格式化的结构使时间更具可读性。包括自定义格式和固定格式。
时间格式转换图
在这里插入图片描述

import time# 生成timestamptime.time()# 1477471508.05#struct_time to timestamptime.mktime(time.localtime())#生成struct_time# timestamp to struct_time 本地时间time.localtime()time.localtime(time.time())# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=16, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0)# timestamp to struct_time 格林威治时间time.gmtime()time.gmtime(time.time())# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=8, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0)#format_time to struct_timetime.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X')# time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1)#生成format_time#struct_time to format_timetime.strftime("%Y-%m-%d %X")time.strftime("%Y-%m-%d %X",time.localtime())# 2016-10-26 16:48:41#生成固定格式的时间表示格式time.asctime(time.localtime())time.ctime(time.time())# Wed Oct 26 16:45:08 2016#struct_time元组元素结构属性                            值tm_year(年)                  比如2011 tm_mon(月)                   1 - 12tm_mday(日)                  1 - 31tm_hour(时)                  0 - 23tm_min(分)                   0 - 59tm_sec(秒)                   0 - 61tm_wday(weekday)             0 - 6(0表示周日)tm_yday(一年中的第几天)        1 - 366tm_isdst(是否是夏令时)        默认为-1

format time结构化表示

在这里插入图片描述

常见结构化时间组合:print time.strftime("%Y-%m-%d %X")#2016-10-26 20:50:13time加减#timestamp加减单位以秒为单位import timet1 = time.time()t2=t1+10print time.ctime(t1)#Wed Oct 26 21:15:30 2016print time.ctime(t2)#Wed Oct 26 21:15:40 2016

datetime模块

datatime模块重新封装了time模块,提供更多接口,提供的类有:date,time,datetime,timedelta,tzinfo。

date类
datetime.date(year, month, day)静态方法和字段date.max、date.min:date对象所能表示的最大、最小日期;date.resolution:date对象表示日期的最小单位。这里是天。date.today():返回一个表示当前本地日期的date对象;date.fromtimestamp(timestamp):根据给定的时间戮,返回一个date对象; output 方法和属性d1 = date(2011,06,03)#date对象d1.year、date.month、date.day:年、月、日;d1.replace(year, month, day):生成一个新的日期对象,用参数指定的年,月,日代替原有对象中的属性。(原有对象仍保持不变)d1.timetuple():返回日期对应的time.struct_time对象;d1.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此类推;d1.isoweekday():返回weekday,如果是星期一,返回1;如果是星期2,返回2,以此类推;d1.isocalendar():返回格式如(year,month,day)的元组;d1.isoformat():返回格式如'YYYY-MM-DD’的字符串;d1.strftime(fmt):和time模块format相同。
time类
datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ) 静态方法和字段time.min、time.max:time类所能表示的最小、最大时间。其中,time.min = time(0, 0, 0, 0), time.max = time(23, 59, 59, 999999);time.resolution:时间的最小单位,这里是1微秒; 方法和属性t1 = datetime.time(10,23,15)#time对象t1.hour、t1.minute、t1.second、t1.microsecond:时、分、秒、微秒;t1.tzinfo:时区信息;t1.replace([ hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ):创建一个新的时间对象,用参数指定的时、分、秒、微秒代替原有对象中的属性(原有对象仍保持不变);t1.isoformat():返回型如"HH:MM:SS"格式的字符串表示;t1.strftime(fmt):同time模块中的format;
datetime类
datetime相当于date和time结合起来。datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] )静态方法和字段datetime.today():返回一个表示当前本地时间的datetime对象;datetime.now([tz]):返回一个表示当前本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间;datetime.utcnow():返回一个当前utc时间的datetime对象;#格林威治时间datetime.fromtimestamp(timestamp[, tz]):根据时间戮创建一个datetime对象,参数tz指定时区信息;datetime.utcfromtimestamp(timestamp):根据时间戮创建一个datetime对象;datetime.combine(date, time):根据date和time,创建一个datetime对象;datetime.strptime(date_string, format):将格式字符串转换为datetime对象;方法和属性dt=datetime.now()#datetime对象dt.year、month、day、hour、minute、second、microsecond、tzinfo:dt.date():获取date对象;dt.time():获取time对象;dt. replace ([ year[ , month[ , day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ] ] ]):dt. timetuple ()dt. utctimetuple ()dt. toordinal ()dt. weekday ()dt. isocalendar ()dt. isoformat ([ sep] )dt. ctime ():返回一个日期时间的C格式字符串,等效于time.ctime(time.mktime(dt.timetuple()));dt. strftime (format)
timedelta类,时间加减
使用timedelta可以很方便的在日期上做天days,小时hour,分钟,秒,毫秒,微妙的时间计算,如果要计算月份则需要另外的办法。#coding:utf-8from  datetime import *dt = datetime.now()#日期减一天dt1 = dt + timedelta(days=-1)#昨天dt2 = dt - timedelta(days=1)#昨天dt3 = dt + timedelta(days=1)#明天delta_obj = dt3-dtprint type(delta_obj),delta_obj#
1 day, 0:00:00print delta_obj.days ,delta_obj.total_seconds()#1 86400.0

hashlib加密

hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法

#!/usr/bin/env python# -*- coding: UTF-8 -*-#pyversion:python3.5#owner:fuzjimport hashlib# ######## md5 ########string = "beyongjie"md5 = hashlib.md5()md5.update(string.encode('utf-8'))     #注意转码res = md5.hexdigest()print("md5加密结果:",res)# ######## sha1 ########sha1 = hashlib.sha1()sha1.update(string.encode('utf-8'))res = sha1.hexdigest()print("sha1加密结果:",res)# ######## sha256 ########sha256 = hashlib.sha256()sha256.update(string.encode('utf-8'))res = sha256.hexdigest()print("sha256加密结果:",res)# ######## sha384 ########sha384 = hashlib.sha384()sha384.update(string.encode('utf-8'))res = sha384.hexdigest()print("sha384加密结果:",res)# ######## sha512 ########sha512= hashlib.sha512()sha512.update(string.encode('utf-8'))res = sha512.hexdigest()print("sha512加密结果:",res)输出结果md5加密结果: 0e725e477851ff4076f774dc312d4748sha1加密结果: 458d32be8ea38b66300174970ab0a8c0b734252fsha256加密结果: 1e62b55bfd02977943f885f6a0998af7cc9cfb95c8ac4a9f30ecccb7c05ec9f4sha384加密结果: e91cdf0d2570de5c96ee84e8a12cddf16508685e7a03b3e811099cfcd54b7f52183e20197cff7c07f312157f0ba4875bsha512加密结果: 3f0020a726e9c1cb5d22290c967f3dd1bcecb409a51a8088db520750c876aaec3f17a70d7981cd575ed4b89471f743f3f24a146a39d59f215ae3e208d0170073#注意:hashlib 加密的字符串类型为二进制编码,直接加密字符串会报如下错误:sha1 = hashlib.sha1()sha1.update(string)res = sha1.hexdigest()print("sha1加密结果:",res)TypeError: Unicode-objects must be encoded before hashing可以使用encode进行转换shaa1 = hashlib.sha1()shaa1.update(string.encode('utf-8'))res = shaa1.hexdigest()print("sha1采用encode转换加密结果:",res) 或者使用byte转换为二进制shab1 = hashlib.sha1()shab1.update(bytes(string,encoding='utf-8'))res = shab1.hexdigest()print("sha1采用byte转换的结果:",res)以上输出:sha1采用encode转换加密结果: 458d32be8ea38b66300174970ab0a8c0b734252fsha1采用byte转换的结果: 458d32be8ea38b66300174970ab0a8c0b734252f

常用方法

hash.update(arg) 更新哈希对象以字符串参数, 注意:如果同一个hash对象重复调用该方法,则m.update(a); m.update(b) 等效于 m.update(a+b),看下面例子m = hashlib.md5()m.update('a'.encode('utf-8'))res = m.hexdigest()print("第一次a加密:",res)m.update('b'.encode('utf-8'))res = m.hexdigest()print("第二次b加密:",res)m1 = hashlib.md5()m1.update('b'.encode('utf-8'))res = m1.hexdigest()print("b单独加密:",res)m2 = hashlib.md5()m2.update('ab'.encode('utf-8'))res = m2.hexdigest()print("ab单独加密:",res)输出结果:第一次a加密: 0cc175b9c0f1b6a831c399e269772661第二次b加密: 187ef4436122d1cc2f40dc2b92f0eba0b单独加密: 92eb5ffee6ae2fec3ad71c777531578fab单独加密: 187ef4436122d1cc2f40dc2b92f0eba0hash.digest() 返回摘要,作为二进制数据字符串值,hash.hexdigest() 返回摘要,作为十六进制数据字符串值,hash.copy() 复制

高级加密

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

low = hashlib.md5()low.update('ab'.encode('utf-8'))res = low.hexdigest()print("普通加密:",res)high = hashlib.md5(b'beyondjie')high.update('ab'.encode('utf-8'))res = high.hexdigest()print("采用key加密:",res)输出结果:普通加密: 187ef4436122d1cc2f40dc2b92f0eba0采用key加密: 1b073f6b8cffe609751e4c98537b7653

logging模块

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;

配置logging基本的设置,然后在控制台输出日志import logginglogging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')logger = logging.getLogger(__name__)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")logger.info("Finish")运行时,控制台输出,2016-10-09 19:11:19,434 - __main__ - INFO - Start print log2016-10-09 19:11:19,434 - __main__ - WARNING - Something maybe fail.2016-10-09 19:11:19,434 - __main__ - INFO - Finish

logging中可以选择很多消息级别,如debug、info、warning、error以及critical。通过赋予logger或者handler不同的级别,开发者就可以只输出错误信息到特定的记录文件,或者在调试时只记录调试信息。

例如,我们将logger的级别改为DEBUG,再观察一下输出结果,

logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')控制台输出,可以发现,输出了debug的信息。2016-10-09 19:12:08,289 - __main__ - INFO - Start print log2016-10-09 19:12:08,289 - __main__ - DEBUG - Do something2016-10-09 19:12:08,289 - __main__ - WARNING - Something maybe fail.2016-10-09 19:12:08,289 - __main__ - INFO - Finish

logging.basicConfig函数各参数:

filename:指定日志文件名;
filemode:和file函数意义相同,指定日志文件的打开模式,‘w’或者’a’;
format:指定输出的格式和内容,format可以输出很多有用的信息,

参数:作用%(levelno)s:打印日志级别的数值%(levelname)s:打印日志级别的名称%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]%(filename)s:打印当前执行程序名%(funcName)s:打印日志的当前函数%(lineno)d:打印日志的当前行号%(asctime)s:打印日志的时间%(thread)d:打印线程ID%(threadName)s:打印线程名称%(process)d:打印进程ID%(message)s:打印日志信息datefmt:指定时间格式,同time.strftime();level:设置日志级别,默认为logging.WARNNING;stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略;设置logging,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到logger,然后将日志写入到指定的文件中import logginglogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)handler = logging.FileHandler("log.txt")handler.setLevel(logging.INFO)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)logger.addHandler(handler)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")logger.info("Finish")log.txt中日志数据为,2016-10-09 19:01:13,263 - __main__ - INFO - Start print log2016-10-09 19:01:13,263 - __main__ - WARNING - Something maybe fail.2016-10-09 19:01:13,263 - __main__ - INFO - Finishlogger中添加StreamHandler,可以将日志输出到屏幕上,import logginglogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)handler = logging.FileHandler("log.txt")handler.setLevel(logging.INFO)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)console = logging.StreamHandler()console.setLevel(logging.INFO)logger.addHandler(handler)logger.addHandler(console)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")logger.info("Finish")可以在log.txt文件和控制台中看到,2016-10-09 19:20:46,553 - __main__ - INFO - Start print log2016-10-09 19:20:46,553 - __main__ - WARNING - Something maybe fail.2016-10-09 19:20:46,553 - __main__ - INFO - Finish可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,logging中包含的handler主要有如下几种andler名称:位置;作用StreamHandler:logging.StreamHandler;日志输出到流,可以是sys.stderr,sys.stdout或者文件FileHandler:logging.FileHandler;日志输出到文件BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滚方式RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP socketsDatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP socketsSMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址SysLogHandler:logging.handlers.SysLogHandler;日志输出到syslogNTEventLogHandler:logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定bufferHTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器

日志回滚

使用RotatingFileHandler,可以实现日志回滚

import loggingfrom logging.handlers import RotatingFileHandlerlogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)#定义一个RotatingFileHandler,最多备份3个日志文件,每个日志文件最大1KrHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3)rHandler.setLevel(logging.INFO)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')rHandler.setFormatter(formatter)console = logging.StreamHandler()console.setLevel(logging.INFO)console.setFormatter(formatter)logger.addHandler(rHandler)logger.addHandler(console)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")logger.info("Finish")可以在工程目录中看到,备份的日志文件,2016/10/09  19:36               732 log.txt2016/10/09  19:36               967 log.txt.12016/10/09  19:36               985 log.txt.22016/10/09  19:36               976 log.txt.3

设置消息的等级

可以设置不同的日志等级,用于控制日志的输出,
日志等级:使用范围
FATAL:致命错误
CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
ERROR:发生错误时,如IO操作失败或者连接问题
WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误
INFO:处理请求或者状态变化等日常事务
DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态

捕获traceback

Python中的traceback模块被用于跟踪异常返回信息,可以在logging中记录下traceback

import logginglogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)handler = logging.FileHandler("log.txt")handler.setLevel(logging.INFO)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)console = logging.StreamHandler()console.setLevel(logging.INFO)logger.addHandler(handler)logger.addHandler(console)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")try:open("sklearn.txt","rb")except (SystemExit,KeyboardInterrupt):raiseexcept Exception:logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)logger.info("Finish")控制台和日志文件log.txt中输出,Start print logSomething maybe fail.Faild to open sklearn.txt from logger.errorTraceback (most recent call last):  File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in 
open("sklearn.txt","rb")IOError: [Errno 2] No such file or directory: 'sklearn.txt'Finish也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info = True,_args),将logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)替换为,logger.exception("Failed to open sklearn.txt from logger.exception")控制台和日志文件log.txt中输出,Start print logSomething maybe fail.Failed to open sklearn.txt from logger.exceptionTraceback (most recent call last): File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in
open("sklearn.txt","rb")IOError: [Errno 2] No such file or directory: 'sklearn.txt'Finish

多模块使用logging

主模块mainModule.py,import loggingimport subModulelogger = logging.getLogger("mainModule")logger.setLevel(level = logging.INFO)handler = logging.FileHandler("log.txt")handler.setLevel(logging.INFO)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)console = logging.StreamHandler()console.setLevel(logging.INFO)console.setFormatter(formatter)logger.addHandler(handler)logger.addHandler(console)logger.info("creating an instance of subModule.subModuleClass")a = subModule.SubModuleClass()logger.info("calling subModule.subModuleClass.doSomething")a.doSomething()logger.info("done with  subModule.subModuleClass.doSomething")logger.info("calling subModule.some_function")subModule.som_function()logger.info("done with subModule.some_function")子模块subModule.py,import loggingmodule_logger = logging.getLogger("mainModule.sub")class SubModuleClass(object):def init(self):self.logger = logging.getLogger("mainModule.sub.module")self.logger.info("creating an instance in SubModuleClass")def doSomething(self):self.logger.info("do something in SubModule")a = []a.append(1)self.logger.debug("list a = " + str(a))self.logger.info("finish something in SubModuleClass")def som_function():module_logger.info("call function some_function")执行之后,在控制和日志文件log.txt中输出,2016-10-09 20:25:42,276 - mainModule - INFO - creating an instance of subModule.subModuleClass2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - creating an instance in SubModuleClass2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.subModuleClass.doSomething2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - do something in SubModule2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - finish something in SubModuleClass2016-10-09 20:25:42,279 - mainModule - INFO - done with  subModule.subModuleClass.doSomething2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.some_function2016-10-09 20:25:42,279 - mainModule.sub - INFO - call function some_function2016-10-09 20:25:42,279 - mainModule - INFO - done with subModule.some_function

首先在主模块定义了logger’mainModule’,并对它进行了配置,就可以在解释器进程里面的其他地方通过getLogger(‘mainModule’)得到的对象都是一样的,不需要重新配置,可以直接使用。定义的该logger的子logger,都可以共享父logger的定义和配置,所谓的父子logger是通过命名来识别,任意以’mainModule’开头的logger都是它的子logger,例如’mainModule.sub’。

实际开发一个application,首先可以通过logging配置文件编写好这个application所对应的配置,可以生成一个根logger,如’PythonAPP’,然后在主函数中通过fileConfig加载logging配置,接着在application的其他地方、不同的模块中,可以使用根logger的子logger,如’PythonAPP.Core’,'PythonAPP.Web’来进行log,而不需要反复的定义和配置各个模块的logger。

通过JSON或者YAML文件配置logging模块

尽管可以在Python代码中配置logging,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。在Python 2.7及以后的版本中,可以从字典中加载logging配置,也就意味着可以通过JSON或者YAML文件加载日志的配置。

通过JSON文件配置

{
"version":1, "disable_existing_loggers":false, "formatters":{
"simple":{
"format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s" } }, "handlers":{
"console":{
"class":"logging.StreamHandler", "level":"DEBUG", "formatter":"simple", "stream":"ext://sys.stdout" }, "info_file_handler":{
"class":"logging.handlers.RotatingFileHandler", "level":"INFO", "formatter":"simple", "filename":"info.log", "maxBytes":"10485760", "backupCount":20, "encoding":"utf8" }, "error_file_handler":{
"class":"logging.handlers.RotatingFileHandler", "level":"ERROR", "formatter":"simple", "filename":"errors.log", "maxBytes":10485760, "backupCount":20, "encoding":"utf8" } }, "loggers":{
"my_module":{
"level":"ERROR", "handlers":["info_file_handler"], "propagate":"no" } }, "root":{
"level":"INFO", "handlers":["console","info_file_handler","error_file_handler"] }}通过JSON加载配置文件,然后通过logging.dictConfig配置logging,import jsonimport logging.configimport osdef setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"):path = default_pathvalue = os.getenv(env_key,None)if value:path = valueif os.path.exists(path):with open(path,"r") as f:config = json.load(f)logging.config.dictConfig(config)else:logging.basicConfig(level = default_level)def func():logging.info("start func")logging.info("exec func")logging.info("end func")if name == "main":setup_logging(default_path = "logging.json")func()

通过YAML文件配置

version: 1disable_existing_loggers: Falseformatters:        simple:            format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"handlers:    console:            class: logging.StreamHandler            level: DEBUG            formatter: simple            stream: ext://sys.stdout    info_file_handler:            class: logging.handlers.RotatingFileHandler            level: INFO            formatter: simple            filename: info.log            maxBytes: 10485760            backupCount: 20            encoding: utf8    error_file_handler:            class: logging.handlers.RotatingFileHandler            level: ERROR            formatter: simple            filename: errors.log            maxBytes: 10485760            backupCount: 20            encoding: utf8loggers:    my_module:            level: ERROR            handlers: [info_file_handler]            propagate: noroot:    level: INFO    handlers: [console,info_file_handler,error_file_handler] 通过YAML加载配置文件,然后通过logging.dictConfig配置logging,import yamlimport logging.configimport osdef setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"):path = default_pathvalue = os.getenv(env_key,None)if value:path = valueif os.path.exists(path):with open(path,"r") as f:config = yaml.load(f)logging.config.dictConfig(config)else:logging.basicConfig(level = default_level)def func():logging.info("start func")logging.info("exec func")logging.info("end func")if name == "main":setup_logging(default_path = "logging.yaml")func()

subprocess模块

subprocess是Python 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。这个模块的目的在于替换几个旧的模块和方法,如:

os.system
os.spawn*
subprocess模块中的常用函数
在这里插入图片描述

说明:在Python 3.5之后的版本中,官方文档中提倡通过subprocess.run()函数替代其他函数来使用subproccess模块的功能;

在Python 3.5之前的版本中,我们可以通过subprocess.call(),subprocess.getoutput()等上面列出的其他函数来使用subprocess模块的功能;
subprocess.run()、subprocess.call()、subprocess.check_call()和subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过subprocess.Popen来完成。
subprocess.getoutput()和subprocess.getstatusoutput()函数是来自Python 2.x的commands模块的两个遗留函数。它们隐式的调用系统shell,并且不保证其他函数所具有的安全性和异常处理的一致性。另外,它们从Python 3.3.4开始才支持Windows平台。

上面各函数的定义及参数说明

函数参数列表:subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)subprocess.getstatusoutput(cmd)subprocess.getoutput(cmd)参数说明:args: 要执行的shell命令,默认应该是一个字符串序列,如['df', '-Th']或('df', '-Th'),也可以是一个字符串,如'df -Th',但是此时需要把shell参数的值置为True。shell: 如果shell为True,那么指定的命令将通过shell执行。如果我们需要访问某些shell的特性,如管道、文件名通配符、环境变量扩展功能,这将是非常有用的。当然,python本身也提供了许多类似shell的特性的实现,如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。check: 如果check参数的值是True,且执行命令的进程以非0状态码退出,则会抛出一个CalledProcessError的异常,且该异常对象会包含 参数、退出状态码、以及stdout和stderr(如果它们有被捕获的话)。stdout, stderr:run()函数默认不会捕获命令执行结果的正常输出和错误输出,如果我们向获取这些内容需要传递subprocess.PIPE,然后可以通过返回的CompletedProcess类实例的stdout和stderr属性或捕获相应的内容;call()和check_call()函数返回的是命令执行的状态码,而不是CompletedProcess类实例,所以对于它们而言,stdout和stderr不适合赋值为subprocess.PIPE;check_output()函数默认就会返回命令执行结果,所以不用设置stdout的值,如果我们希望在结果中捕获错误信息,可以执行stderr=subprocess.STDOUT。input: 该参数是传递给Popen.communicate(),通常该参数的值必须是一个字节序列,如果universal_newlines=True,则其值应该是一个字符串。universal_newlines: 该参数影响的是输入与输出的数据格式,比如它的值默认为False,此时stdout和stderr的输出是字节序列;当该参数的值设置为True时,stdout和stderr的输出是字符串。

subprocess.CompletedProcess类介绍

需要说明的是,subprocess.run()函数是Python3.5中新增的一个高级函数,其返回值是一个subprocess.CompletedPorcess类的实例,因此,subprocess.completedPorcess类也是Python 3.5中才存在的。它表示的是一个已结束进程的状态信息,它所包含的属性如下:

args: 用于加载该进程的参数,这可能是一个列表或一个字符串

returncode: 子进程的退出状态码。通常情况下,退出状态码为0则表示进程成功运行了;一个负值-N表示这个子进程被信号N终止了

stdout: 从子进程捕获的stdout。这通常是一个字节序列,如果run()函数被调用时指定universal_newlines=True,则该属性值是一个字符串。如果run()函数被调用时指定stderr=subprocess.STDOUT,那么stdout和stderr将会被整合到这一个属性中,且stderr将会为None

stderr: 从子进程捕获的stderr。它的值与stdout一样,是一个字节序列或一个字符串。如果stderr灭有被捕获的话,它的值就为None

check_returncode(): 如果returncode是一个非0值,则该方法会抛出一个CalledProcessError异常。

实例

subprocess.run()>>> subprocess.run(["ls", "-l"])  # doesn't capture outputCompletedProcess(args=['ls', '-l'], returncode=0)>>> subprocess.run("exit 1", shell=True, check=True)Traceback (most recent call last):...subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')subprocess.call()>>> subprocess.call(['ls',  '-l'])总用量 160drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面0>>> subprocess.call('ls -l', shell=True)总用量 160drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面0>>> subprocess.call(['ls',  '-l'], stdout=subprocess.DEVNULL)0>>> subprocess.call(['ls',  '-l', '/test'])ls: 无法访问/test: 没有那个文件或目录2suprocess.check_call()>>> subprocess.check_call(['ls',  '-l'])总用量 160drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面0>>> subprocess.check_call('ls -l', shell=True)总用量 160drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板drwxr-xr-x  2 wader wader   4096 12月  7  2015 视频drwxr-xr-x  2 wader wader   4096 12月  7  2015 图片drwxr-xr-x  2 wader wader   4096 12月  7  2015 文档drwxr-xr-x  2 wader wader   4096  4月 13  2016 下载drwxr-xr-x  2 wader wader   4096 12月  7  2015 音乐drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面0>>> subprocess.check_call('ls -l /test', shell=True)ls: 无法访问/test: 没有那个文件或目录Traceback (most recent call last):  File "
", line 1, in
File "/usr/lib/python3.4/subprocess.py", line 557, in check_call raise CalledProcessError(retcode, cmd)subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2sbuprocess.check_output()>>> ret = subprocess.check_output(['ls', '-l'])>>> print(ret)b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x 2 wader wader 4096 4\xe6\x9c\x88 13 2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x 7 wader wader 4096 5\xe6\x9c\x88 26 2016 \xe6\xa1\x8c\xe9\x9d\xa2\n'>>> ret = subprocess.check_output(['ls', '-l'], universal_newlines=True)>>> print(ret)总用量 160drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面subprocess.getoutput()与subprocess.getstatusoutput()>>> ret = subprocess.getoutput('ls -l')>>> print(ret)总用量 160drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面>>> retcode, output = subprocess.getstatusoutput('ls -l')>>> print(retcode)0>>> print(output)总用量 160drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面>>> retcode, output = subprocess.getstatusoutput('ls -l /test')>>> print(retcode)2>>> print(output)ls: 无法访问/test: 没有那个文件或目录

转载地址:https://blog.csdn.net/qq_45206551/article/details/105123323 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:用nginx做反向代理
下一篇:python 用socket搭建socket服务器-多线程网络编程

发表评论

最新留言

很好
[***.229.124.182]2024年10月04日 09时09分35秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章