python基础(五)
一、模块的介绍
1.模块的定义、用途
模块就是具有一定功能的程序块,实质上模块就是.py格式的文件,每个文件就是一个模块。模块可以把复杂的程序按功能分开,分别用不同的文件名存放。目的是使程序代码能够重用,也使得程序更便于维护。
python模块分为三类:(1)内置模块;(2)第三方模块;(3)自定义模块。
2.模块的导入
模块使用前需要先导入,导入的方式常用的有:
(1). import + 模块的名称
(2). from 模块名称 import 函数名称
3.包的引用
Python的文件有一种组织,就是将几个功能相近的模块可组成一个python包,存放到一个目录结构,通过输入包的路径调用包中模块的变量、函数等。每个包下面都有个初始化文件__init__.py,该文件可以为空,也可以定义相关代码。包的引用有三种方式:
(1)import [package name]只能使用初始化文件对象;
(2)imoport [package name].[module name]可以使用引用模块的对象;
(3) from [package name] import [function name]与第二种方式相同,可以使用引用模块的对象。
二、常用内置模块
2.1 os&sys模块
1 import os,sys 2 print (os.path.abspath(__file__)) #文件的绝对路径 3 print(os.path.dirname(os.path.abspath(__file__))) #文件路径的文件夹路径 4 print (os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) #文件所在位置的父路径 5 path_base=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 6 sys.path.append(path_base) #将这个路径添加到环境变量,即可以导入这个目录下的模块
输出结果:
C:\Users\Administrator\PycharmProjects\python\day5\练习\os.py
C:\Users\Administrator\PycharmProjects\python\day5\练习
C:\Users\Administrator\PycharmProjects\python\day5
os模块提供对操作系统调用的接口:
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串(当前系统的分隔符) os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
2.2 time&datetime模块
1 import time 2 print (time.time()) #time()时间戳,1970年到现在的秒数 3 time.sleep(3) #停顿三秒钟 4 print(time.gmtime()) #时间戳换成UTC时区的时间的元组,不加参数模式人当前时间戳 5 print(time.gmtime(1422197875)) #加参数后返回此时间戳换成时间元组 6 print(time.localtime()) #元组形式获得当前时间 7 print (time.mktime(time.localtime())) #将元组形式换算成时间戳 8 print (time.localtime().tm_year,time.localtime().tm_mon) #获取当前时间元组中的年份和月份
输出结果:
1472198061.0441651
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=26, tm_hour=7, tm_min=54, tm_sec=24, tm_wday=4, tm_yday=239, tm_isdst=0)
time.struct_time(tm_year=2015, tm_mon=1, tm_mday=25, tm_hour=14, tm_min=57, tm_sec=55, tm_wday=6, tm_yday=25, tm_isdst=0)
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=26, tm_hour=15, tm_min=54, tm_sec=24, tm_wday=4, tm_yday=239, tm_isdst=0)
1472198064.0
2016 8
strftime(“格式”,时间的元组形式)#将当前时间(元组形式)转换成格式化的字符串时间
1 import time 2 print (time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())) #按我们制定的格式输出我们的当前时间 3 print (time.strftime("%H:%M:%S",time.localtime())) #只输出今天的时间格式
输出结果:
2016-08-26 16:02:50
16:02:50
为什么这样先对照显示呢,是因为:
%
a 本地(locale)简化星期名称
%
A 本地完整星期名称
%
b 本地简化月份名称
%
B 本地完整月份名称
%
c 本地相应的日期和时间表示
%
d 一个月中的第几天(
01
-
31
)
%
H 一天中的第几个小时(
24
小时制,
00
-
23
)
%
I 第几个小时(
12
小时制,
01
-
12
)
%
j 一年中的第几天(
001
-
366
)
%
m 月份(
01
-
12
)
%
M 分钟数(
00
-
59
)
%
p 本地am或者pm的相应符 一
%
S 秒(
01
-
61
) 二
%
U 一年中的星期数。(
00
-
53
星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第
0
周。 三
%
w 一个星期中的第几天(
0
-
6
,
0
是星期天) 三
%
W 和
%
U基本相同,不同的是
%
W以星期一为一个星期的开始。
%
x 本地相应日期
%
X 本地相应时间
%
y 去掉世纪的年份(
00
-
99
)
%
Y 完整的年份
%
Z 时区的名字(如果不存在为空字符)
%
%
‘
%
’字符
1 import time 2 print(time.strptime('2016-08-26',"%Y-%m-%d")) #将我们给的时间格式转换成元组的形式,前面的时间格式跟后面的%Y这些事要一一对应的 3 print (time.strptime('2016-08-03',"%Y-%d-%m"))#这里我把%d和%m反过来了,可以看到效果。
输出结果:
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=239, tm_isdst=-1)
time.struct_time(tm_year=2016, tm_mon=3, tm_mday=8, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=68, tm_isdst=-1)
asctime()#将元组形式的时间转换成字符串,不加参数,默认是localtime()
1 import time 2 print(time.asctime())
输出结果:
Fri Aug 26 16:37:12 2016
时间加减
1 import datetime,time 2 print(datetime.datetime.now()) #输出当前时间 3 print(datetime.date.fromtimestamp(time.time())) #时间戳直接转换为时间格式 4 print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间加三天 5 print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间减三天 6 print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间加三小时 7 print(datetime.datetime.now() + datetime.timedelta(minutes=30))#当前时间加30分钟 8 c_time=datetime.datetime.now() 9 print(c_time) #输出当前时间,只要是跟下面的时间转换对照一下 10 print(c_time.replace(minute=3,hour=2))#当前时间的小时换成2点,分钟换成3分
输出结果:
2016-08-26 16:45:03.530185
2016-08-26
2016-08-29 16:45:03.530185
2016-08-23 16:45:03.530185
2016-08-26 19:45:03.530185
2016-08-26 17:15:03.530185
2016-08-26 16:45:03.530185
2016-08-26 02:03:03.530185
2.3 random模块
1 import random 2 print(random.random()) #随机数, 3 print(random.randint(1,3)) 4 ================================== 5 import random 6 print (random.random()) #0.6445010863311293 7 #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0 8 print (random.randint(1,7)) #4 9 #random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。 10 11 # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b 12 print (random.randrange(1,10)) #5 13 #random.randrange的函数原型为:random.randrange([start], stop[, step]), 14 # 从指定范围内,按指定基数递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2), 15 # 结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。 16 # random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。 17 print(random.choice('liukuni')) #i 18 #random.choice从序列中获取一个随机元素。 19 # 其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。 20 # 这里要说明一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。 21 # list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。 22 # 下面是使用choice的一些例子: 23 print(random.choice("学习Python"))#学 24 print(random.choice(["JGood","is","a","handsome","boy"])) #List 25 print(random.choice(("Tuple","List","Dict"))) #List 26 print(random.sample([1,2,3,4,5],3)) #[1, 2, 5] 27 #random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改 28 例: 29 import random 30 import string 31 #随机整数: 32 print( random.randint(0,99)) #70 33 #随机选取0到100间的偶数: 34 print(random.randrange(0, 101, 2)) #4 35 #随机浮点数: 36 print( random.random()) #0.2746445568079129 37 print(random.uniform(1, 10)) #9.887001463194844 38 #随机字符: 39 print(random.choice('abcdefg&#%^*f')) #f 40 41 #多个字符中选取特定数量的字符: 42 print(random.sample('abcdefghij',3)) #['f', 'h', 'd'] 43 44 #随机选取字符串: 45 print( random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )) #apple 46 47 #洗牌# 48 items = [1,2,3,4,5,6,7] 49 print(items) #[1, 2, 3, 4, 5, 6, 7] 50 random.shuffle(items) 51 print(items) #[1, 4, 7, 2, 5, 3, 6]
2.4 logging模块
介绍:
Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。
logging模块与log4j的机制是一样的,只是具体的实现细节不同。模块提供logger,handler,filter,formatter。
logger:提供日志接口,供应用代码使用。logger最长用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
handler:将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
filter:提供一种优雅的方式决定一个日志记录是否发送到handler。
formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。
与log4j类似,logger,handler和日志消息的调用可以有具体的日志级别(Level),只有在日志消息的级别大于logger和handler的级别。
(1). 将日志打印到屏幕
1 import logging 2 logging.debug('This is debug message---test1') 3 logging.info('This is info message---test2') 4 logging.warning('This is warning message---test3') 5 logging.error('This is warning message---test4') 6 logging.critical('This is warning message---test5')
输出结果:
WARNING:root:This is warning message---test3
ERROR:root:This is warning message---test4
CRITICAL:root:This is warning message---test5
默认情况下,logging将日志打印到屏幕,日志级别为WARNING;
日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,日志级别可以自己定义。
(2). 通过logging.basicConfig函数配置日志的输出格式及方式
1 import logging 2 logging.basicConfig(level=logging.DEBUG, 3 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', 4 datefmt='%a,%d %b %Y %H:%M:%S', 5 filename='mytest.log', 6 filemode='w') 7 logging.debug('This is debug message by hehe') 8 logging.info('This is info message by haha') 9 logging.warning('This is warning message by wawa')
输出结果:
cat mytest.log
Sat,27 Aug 2016 07:49:30 loglx.py[line:15] DEBUG This is debug message by hehe
Sat,27 Aug 2016 07:49:30 loglx.py[line:16] INFO This is info message by haha
Sat,27 Aug 2016 07:49:30 loglx.py[line:17] WARNING This is warning message by wawa
1 logging.basicConfig函数各参数: 2 filename: 指定日志文件名 3 filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a' 4 format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示: 5 %(levelno)s: 打印日志级别的数值 6 %(levelname)s: 打印日志级别名称 7 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0] 8 %(filename)s: 打印当前执行程序名 9 %(funcName)s: 打印日志的当前函数 10 %(lineno)d: 打印日志的当前行号 11 %(asctime)s: 打印日志的时间 12 %(thread)d: 打印线程ID 13 %(threadName)s: 打印线程名称 14 %(process)d: 打印进程ID 15 %(message)s: 打印日志信息 16 datefmt: 指定时间格式,同time.strftime() 17 level: 设置日志级别,默认为logging.WARNING 18 stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
(3). 将日志同时输出到文件和屏幕
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a,%d %b %Y %H:%M:%S', filename='mytest.log', filemode='w') #定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象# console=logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) ################################################################################################# logging.debug('This is debug message by hehe') logging.info('This is info message by haha') logging.warning('This is warning message by wawa')
(4).logging之日志回滚
1 import logging 2 from logging.handlers import RotatingFileHandler 3 ############################################################################################## 4 #定义一个RotatingFileHandler,最多备份5个日志文件,每个日志文件最大10M(自定义) 5 Rthandler=RotatingFileHandler('myweb.log',maxBytes=10*1024*1024,backupCount=5) 6 Rthandler.setLevel(logging.INFO) 7 formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') 8 Rthandler.setFormatter(formatter) 9 logging.getLogger('').addHandler(Rthandler)
从上例和本例可以看出,logging有一个日志处理的主对象,其它处理方式都是通过addHandler添加进去的。
logging的几种handle方式如下:
1 logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件 2 logging.FileHandler: 日志输出到文件 3 日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler 4 logging.handlers.BaseRotatingHandler 5 logging.handlers.RotatingFileHandler 6 logging.handlers.TimedRotatingFileHandler 7 logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets 8 logging.handlers.DatagramHandler: 远程输出日志到UDP sockets 9 logging.handlers.SMTPHandler: 远程输出日志到邮件地址 10 logging.handlers.SysLogHandler: 日志输出到syslog 11 logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志 12 logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer 13 logging.handlers.HTTPHandler: 通过"GET"或"POST"远程输出到HTTP服务器
由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中。