os模块(补充中)
1.查看当前路径及切换路径
>>> import os
>>> os.getcwd() #获取当前文件所在的路径
'D:\python\Lib\idlelib'
>>> os.chdir('../') #切换当上一层目录,此处可以是相对路径
>>> os.getcwd()
'D:\python\Lib'
>>> os.chdir('D:Program Files (x86)') #也可以是绝对路径
>>> os.getcwd()
'D:\Program Files (x86)'
补充:
在pycharm上发现os.getcwd()与os.path.realpath("./")返回的都是.py文件的绝对路径,其实不是的,这个目录并不是指脚本所在的目录,而是所运行脚本的目录。
实际上os.path.relpath(path[, start]) #从start开始计算相对路径。
print(__file__)·#返回文件的相对路径,包含文件名称
os.path.abspath(__file__)#返回文件的绝对路径,包含文件名称
os.path.dirname(os.path.abspath(__file__))#上一个路径的文件名称所在的目录,就是当前文件的上一层
dis_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#再往上一层,可以利用这条,通过import sys; sys.path.append(dis_path),将其加到环境变量中,这样就可以实现跨路径调用文件。
2.查看当前路径下的文件是否存在
os.path.exists('文件名'),存在返回True
可以结合上面的切换路径使用,查看不同路径下有没有此文件
3,替换与重命名文件
os.repalce()
replace(*args, **kwargs):
Rename a file or directory, overwriting the destination.
前面文件用后面文件名替换
os.rename()
用法一样,但是有个区别
os.replace(f1,f2) #f2如果存在,f1仍然更名为f2,并将f2替换掉
os.rename(f1,f2)#f2如果存在,就报错
4,执行Linux命令
os.system('commond'),会直接执行命令并将结果返回到屏幕上,如同在系统上执行命令一样
os.popen('commond'),执行命令但是不打印到屏幕上,而是返回一个对象,如果要显示命令,需要read()方法
如:
>>> os.popen('fping 10.1.1.1') <open file 'fping 10.1.1.1', mode 'r' at 0x7f3893b51540> >>> a = os.popen('fping 10.1.1.1') >>> a <open file 'fping 10.1.1.1', mode 'r' at 0x7f3893b515d0> >>> a.read() '10.1.1.1 is alive '
1 提供对操作系统进行调用的接口 2 3 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 4 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd 5 os.curdir 返回当前目录: ('.') 6 os.pardir 获取当前目录的父目录字符串名:('..') 7 os.makedirs('dirname1/dirname2') 可生成多层递归目录 8 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 9 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname 10 os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 11 os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 12 os.remove() 删除一个文件 13 os.rename("oldname","newname") 重命名文件/目录 14 os.stat('path/filename') 获取文件/目录信息 15 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" 16 os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " 17 os.pathsep 输出用于分割文件路径的字符串 18 os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' 19 os.system("bash command") 运行shell命令,直接显示 20 os.environ 获取系统环境变量 21 os.path.abspath(path) 返回path规范化的绝对路径 22 os.path.split(path) 将path分割成目录和文件名二元组返回 23 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 24 os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素 25 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False 26 os.path.isabs(path) 如果path是绝对路径,返回True 27 os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False 28 os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False 29 os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 30 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 31 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
SYS模块
sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称 sys.stdout.write('please:') val = sys.stdin.readline()[:-1]
random模块
1 import random 2 print(random.random()) #打印一个随机的float数 3 print(random.randint(1,5)) #打印1到5之间随机的int数,包括1和5 4 print(random.randrange(1,5)) #打印1到5之间随机的int数,包括1,不包括5
输出:
0.3706594058307373 4 2
实例:生成验证码
1 import random 2 checkcode = '' 3 for i in range(4): 4 current = random.randrange(0,4) 5 if current != i: 6 """chr()返回整数对应的ASCII码中的英文字母,这里65-90代表26个大写字母,97-122返回26个小写字母。相反,ord('a')返回字母a在ascii中对应的数字""" 7 temp = chr(random.randint(65,90)) 8 else: 9 temp = random.randint(0,9) 10 checkcode += str(temp) 11 print(checkcode)
扩展小脚本:考察省跟省会的对应关系,随机生成多份试卷,并生成对应的答案文件。
1 #-*- coding:utf-8 -*- 2 import random,copy 3 4 province_capital = {'江苏省':'南京市', 5 '湖北省': '武汉市', 6 '山东省': '济南市', 7 '新疆': '乌鲁木齐', 8 '内蒙古': '呼和浩特', 9 '西藏': '拉萨', 10 '青海': '西宁', 11 '广东': '广州', 12 '浙江': '杭州', 13 '河北': '石家庄', 14 '江西': '南昌', 15 '广西': '南宁', 16 '山西': '太原'} 17 18 for q_num in range(10): 19 q_file = open('province_capital%d.txt'%(q_num+1),'w',encoding='utf-8') #创建试卷 20 answer_key_file = open('province_capital_answers%d.txt'%(q_num+1),'w',encoding='utf-8') #创建答案文件 21 22 q_file.write('Name: Date: Period: ') 23 q_file.write(('province capital test id:%d '%(q_num+1)).title().center(100))#由于文件还未保存,所以可以继续不覆盖写入 24 q_file.write(' ') 25 capitial = list(province_capital.keys()) #将省存在一个列表中 26 random.shuffle(capitial) #利用random.shuffle()方法打乱顺序 27 for questionnum in range(13): #每个试卷13道题 28 correct_answer = province_capital[capitial[questionnum]] 29 wrong_answers = list(province_capital.values()) 30 del wrong_answers[wrong_answers.index(correct_answer)] 31 wrong_answers = random.sample(wrong_answers,3) 32 wrong_answers.append(correct_answer) 33 answer_options =copy.copy(wrong_answers) #一个正确答案和3个错误构成的列表 34 # print(answer_options) 35 random.shuffle(answer_options) 36 37 q_file.write("%d. What is the captical of %s? "%(questionnum+1,capitial[questionnum])) 38 39 for i in range(4): 40 q_file.write(' %s.%s '%('ABCD'[i],answer_options[i])) 41 q_file.write(' ') 42 43 answer_key_file.write('%d.%s '%(questionnum+1,'ABCD'[answer_options.index(correct_answer)])) 44 q_file.close() 45 answer_key_file.close()
试卷示例:
logging模块(补充中)
日志共有5个级别,由高到低如下:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0(不算)
1,默认情况下,longging只会讲warning以上的级别的日志打印到屏幕上,包括warning。
import logging
# logging.basicConfig()
logging.debug('this is debug')
logging.info('this is info')
logging.warning('this is warning')
logging.error('this is error')
logging.critical('this is critical')
输出:
WARNING:root:this is warning
ERROR:root:this is error
CRITICAL:root:this is critical
2.通过logging.basicConfig函数对日志的输出格式及方式做相关配置
import logging
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10)
logging.debug('this is debug')
logging.info('this is info')
logging.warning('this is warning')
logging.error('this is error')
logging.critical('this is critical')
会生成一个log.log的文件,并将日志追加到文件中:默认是追加。
如下:
2017-05-25 18:09:13 PM - root - DEBUG -logging mod: this is debug
2017-05-25 18:09:13 PM - root - INFO -logging mod: this is info
2017-05-25 18:09:13 PM - root - WARNING -logging mod: this is warning
2017-05-25 18:09:13 PM - root - ERROR -logging mod: this is error
2017-05-25 18:09:13 PM - root - CRITICAL -logging mod: this is critical
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.WARNING
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
以上日志模块参考:http://www.cnblogs.com/dkblog/archive/2011/08/26/2155018.html
如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了
Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:
logger提供了应用程序可以直接使用的接口;
handler将(logger创建的)日志记录发送到合适的目的输出;
filter提供了细度设备来决定输出哪条日志记录;
formatter决定日志记录的最终输出格式。
logger
每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”) #这个chat.gui就是日志内容中的 %(name)s ,默认是root
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)
Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
handler
handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
1) logging.StreamHandler
使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr
2) logging.FileHandler
和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。
3) logging.handlers.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
4) logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨
import logging """创建一个logger""" logger = logging.getLogger('TEST-LOG') logger.setLevel(logging.DEBUG) """创建一个console handler,设置级别为DEBUG,举个例子,如果此处设置的是ERROR,那么只会处理ERROR及以上的级别,即使后面的handler设置的级别为DEBUG,也不会处理,如果后面设置的是CRITICAL,那么只会处理CRITICAL级别的日志""" ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) """创建一个file handler,设置级别为WARNING""" fh = logging.FileHandler("access.log") fh.setLevel(logging.ERROR) """创建formatter""" formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') """为ch和fh添加formatetr""" ch.setFormatter(formatter) fh.setFormatter(formatter) """将ch和fh添加到logger""" logger.addHandler(ch) logger.addHandler(fh) """日志""" logger.debug('debug message') logger.info("info message") logger.warning("warning message") logger.error("error message") logger.critical("critical message") 控制台输出: 2017-06-01 16:51:02,961 - TEST-LOG - DEBUG - debug message 2017-06-01 16:51:02,961 - TEST-LOG - INFO - info message 2017-06-01 16:51:02,961 - TEST-LOG - WARNING - warning message 2017-06-01 16:51:02,961 - TEST-LOG - ERROR - error message 2017-06-01 16:51:02,961 - TEST-LOG - CRITICAL - critical message access.log文件输出 2017-06-01 16:51:02,961 - TEST-LOG - ERROR - error message 2017-06-01 16:51:02,961 - TEST-LOG - CRITICAL - critical message
import logging from logging import handlers logger = logging.getLogger(__name__) log_file = "timelog.log" #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3) fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1") logger.warning("test12") logger.warning("test13") logger.warning("test14")