python常用模块
python常用模块
- 模块简述
- time模块
- random模块
- hashlib模块
- os模块
- sys模块
- logging模块
- json模块
- pickle模块
模块简述
python中模块本质就是一个.py文件,文件内包含了python定义和声明。使用模块可以大大的提高代码的可维护性。
模块的分类
模块主要分为:内置模块,第三方模块,自定义模块
模块的引入
Python中用关键字import来引入某个模块。
-
import 模块名(调用模块内函数需要使用:模块名.函数名())
-
from 模块名 import 函数名1,函数名2....(直接使用函数名即可调用)
示例:
import math
print(math.sqrt(16))
from math import sqrt
print(sqrt(16))
下面介绍下python中常用模块
time模块
在python中,表示时间的三种方式:时间戳,结构化时间,字符串时间。
-
时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的当前时间戳是float类型。
-
格式化的时间字符串(Format String): ‘1988-03-16’
-
元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等,夏令时)
下标/索引 | 属性名称 | 描述 |
---|---|---|
0 | tm_year | 年份,如 2017 |
1 | tm_mon | 月份,取值范围为[1, 12] |
2 | tm_mday | 一个月中的第几天,取值范围为[1-31] |
3 | tm_hour | 小时, 取值范围为[0-23] |
4 | tm_min | 分钟,取值范围为[0, 59] |
5 | tm_sec | 秒,取值范围为[0, 61] |
6 | tm_wday | 一个星期中的第几天,取值范围为[0-6],0表示星期一 |
7 | tm_yday | 一年中的第几天,取值范围为[1, 366] |
8 | tm_isdst | 是否为夏令时,可取值为:0 , 1 或 -1 |
-
可以把它当做一种特殊的有序不可变序列通过 下标/索引 获取各个元素的值,如t[0]
-
也可以通过 .属性名 的方式来获取各个元素的值,如t.tm_year。
示例:
import time
#时间戳
print(time.time()) #返回当前时间时间戳
#结构化时间
print(time.localtime()) #返回当前时间戳对应的结构化时间元组
print(time.localtime().tm_year) #取出元素tm_year
print(time.localtime()[0]) #取出元素tm_year
#字符串时间
print(time.strftime('%Y-%m-%d %X')) #返回当前时间对应的字符串时间
总结
时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的(可以list后修改)。
几种时间形式的相互转换:
时间转换示例:
def foo1(x):
'''将字符串时间转换为时间戳'''
struct_t = time.strptime(x,'%Y-%m-%d')
stamp_t = time.mktime(struct_t)
return stamp_t
def foo2(x):
'''将时间戳转换为字符串时间'''
struc_t = time.localtime(x)
str_t = time.strftime('%Y-%m-%d %X')
return str_t
print(foo1("2016-05-06"))
t = time.time()
print(foo2(t))
#执行结果
1462464000.0
2017-06-21 16:56:55
time.sleep()
sleep(secs)
线程推迟指定的时间运行,单位为秒。遇到sleep即I/O阻塞,不占用CPU。
random模块
>>> import random
>>> random.random() #随机得出大于0小于1之间的小数(float)
0.2563367655587043
>>> random.randint(0,9) #随机得出大于等于0且小于等于9之间的整数
8
>>> random.randrange(1,3) #随机得出大于等于1且小于3之间的整数
1
>>> random.choice(['1','a','tom']) #随机取出后面列表内的一个元素
'1'
>>> random.sample(['1','a','tom','bob'],2) #随机取出列表内两个元素的组合
['a', 'bob']
>>> random.uniform(1,3) #随机取出大于1小于3的小数
1.5434039770049992
>>> item=[1,3,5,7,9]
>>> random.shuffle(item) # 打乱次序
>>> item
[5, 1, 3, 7, 9]
>>> random.shuffle(item)
>>> item
[5, 9, 7, 1, 3]
应用实例:
生成一个5位数的包含数字和大小写字母的验证码
import random
def verfication_code():
code = ''
for i in range(5):
num = random.randint(0,9) #生成1位数数字
ch1 = chr(random.randint(65,90)) #生成大写字母
ch2 = chr(random.randint(97,122)) #生成小写字母
sum_code = random.choice([str(num),ch1,ch2]) #随机取一
code = code + sum_code
return code
print(verfication_code())
hashlib模块
hashlib提供摘要算法 ,摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib
md5_obj = hashlib.md5() #创建md5对象
md5_obj.update(b'hello') #传入参数
print(md5_obj.hexdigest()) #获取摘要值
mb = hashlib.md5()
mb.update('hello'.encode('utf-8'))
print(mb.hexdigest())
#执行结果
5d41402abc4b2a76b9719d911017c592
5d41402abc4b2a76b9719d911017c592
摘要算法应用:
网站账号和口令信息一般存放在后台数据库内,如果直接存放明文信息,一般数据库维护人员能够直接查看到,一旦泄露也非常危险。因此正确的打开方式应该是口令信息存储摘要值。
username | password
---------+---------------------------------
michael | e10adc3949ba59abbe56e057f20f883e
bob | 878ef96e86145580c38c87f0410ad153
alice | 99b1c2188db85afee403b1536010c2c9
需要注意的是,存储摘要信息也会有可能遇到问题,如果网站用户的口令设置非常简单如:admin,123456等等,黑客如果能够得到数据库信息就能够事先计算摘要得到一个反推表,这样一比对也能获得密码。
要解决这方面问题,一方面拒绝用户输入简单口令,另外还可以设计存储用户口令摘要信息前复杂化一下,俗称“加盐”:
password + ‘Salt’然后生成摘要信息存储(更复杂可以使用username + password + ‘Salt’)
os模块
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下为’\r\n’,Linux下为’\n’
os.pathsep #输出用于分割文件路径的字符串 win下为’;’,Linux下为’:’
os.name #输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system(‘bash command’) #运行shell命令,直接显示
os.environ #获取系统环境变量
os.path.abspath(path) #返回path规范化的绝对路径
os.path.realpath(path) #返回path规范化的绝对路径
os.path.split(path) #将path分割成目录和文件名二元组返回
os.path.dirname(path) #返回path的目录,即是os.path.split(path)的第一个元素
os.path.basename(path) #返回path最后的文件名,即os.path.split(path)的第二个元素。如果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所指向的文件或者目录的最后修改时间
os.path.getsize(path) #返回path所指向的文件或目录的大小
os.walk(top, topdown = True, onerror = None, followlinks = False)
#第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。
#dirpath 是一个string,代表目录的路径,
#dirnames 是一个list,包含了dirpath下所有子目录的名字。
#filenames 是一个list,包含了非目录文件的名字。
#这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).
sys模块
sys.argv 命令行参数列表,第一个元素为执行py脚本路径
sys.exit(n) 程序的退出,n=0时为正常退出
sys.path 获取指定模块搜索路径的字符串集合,可以将写好的
模块放在得到的某个路径下,就可以在程序中import时正确找到。
sys.platform 返回操作系统平台名称
sys.argv
#py文件内容:
#!/usr/bin/env python
import sys
print(sys.argv[0])
print(sys.argv[1])
print(sys.argv[2])
#cmd命令行执行结果:
C:> python scripts.py canshu1 canshu2
scripts.py
canshu1
canshu2
sys.exit(n)
python在默认执行脚本的时候会由头执行到尾,然后自动退出,如果需要中途退出程序则需要使用sys.exit()函数。
import sys
count = 0
while True:
if count == 5:
sys.exit()
print(count,end=' ')
count += 1
print('hello,world!')
#执行结果
0 1 2 3 4
发现满足条件直接退出py的执行了,后面的py语句不会执行。
sys.path
import sys
sys.path.append(r'D:\自定义目录\练习小程序') #写好的模块的路径加入sys.path
print(sys.path)
from test1 import foo #导入自定义模块
foo() #正常调用test1文件的函数
logging模块
简单使用测试
import logging
logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')
输出:
WARNING:root:warn message #日志级别:logger实例名称:日志消息内容
ERROR:root:error message
CRITICAL:root:critical message
默认情况下,logging模块将日志打印到屏幕上(stdout),日志级别为WARNING(即只有日志级别高于WARNING的日志信息才会输出)
配置日志输出
日志级别:
级别 | 何时使用 |
---|---|
DEBUG | 详细信息,典型地调试问题时会感兴趣。 |
INFO | 证明事情按预期工作。 |
WARNING | 表明发生了一些意外,或者不久的将来会发生问题(如‘磁盘满了’)。软件还是在正常工作。 |
ERROR | 由于更严重的问题,软件已不能执行一些功能了。 |
CRITICAL | 严重错误,表明软件已不能继续运行了。 |
简单配置
通过basicConfig配置
import logging
#指定basicConfig配置内容如下
logging.basicConfig(format='%(asctime)s---%(name)s---%(levelname)s---%(message)s',
filename='logger.log',
filemode='w',
level=logging.INFO)
logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')
最终结果:
在当前目录下生成logger.log文件,内容如下:
2017-06-22 21:46:47,880---root---INFO---info message
2017-06-22 21:46:47,880---root---WARNING---warn message
2017-06-22 21:46:47,880---root---ERROR---error message
2017-06-22 21:46:47,880---root---CRITICAL---critical message
basicConfig关键字参数
关键字 | 描述 |
---|---|
filename | 创建一个FileHandler,使用指定的文件名,而不是使用StreamHandler。 |
filemode | 如果指明了文件名,指明打开文件的模式(如果没有指明filemode,默认为'a')。 |
format | handler使用指明的格式化字符串。 |
datefmt | 使用指明的日期/时间格式。 |
level | 指明根logger的级别。 |
stream | 使用指明的流来初始化StreamHandler。 |
stream关键字参数与'filename'不兼容,如果两个都
有,'stream'被忽略。用指定的stream创建StreamHandler。
可以指定输出到sys.stderr,sys.stdout或者
文件(f=open(‘test.log’,’w’)),默认为sys.stderr。
#简单的说就是文件流和屏幕流只支持一个,不同时支持。要想都
支持需要通过logger对象配置
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 | 打印日志的时间 |
%(thread)d | 打印线程id |
%(threadName)s | 打印线程名称 |
%(process)d | 打印进程ID |
%(message)s | 打印日志信息 |
通过logger对象配置
import logging
# 创建记录器Logger #reate logger
logger_name = "example" #设置logger名字
logger = logging.getLogger(logger_name) #创建logger实例
logger.setLevel(logging.DEBUG) #设置logger默认级别
# 创建处理器Handler #create file handler
log_path = "./log.log" #定义日志文件路径
fh = logging.FileHandler(log_path,mode='a') #创建文件处理器(存储到文件中,模式为a追加)
fh.setLevel(logging.WARN) #设置文件日志存储的级别
# 这里再测试创建一个handler用于输出到控制台
ch = logging.StreamHandler()
# 创建格式化器Formatter #create formatter
fmt = "%(asctime)-15s %(levelname)s %(name)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S" #不使用datefmt也没问题
formatter = logging.Formatter(fmt, datefmt) #不使用datefmt设置datefmt=None
# logger对象可以添加多个Handler对象 #add handler and formatter to logger
fh.setFormatter(formatter)
logger.addHandler(fh)
ch.setFormatter(formatter)
logger.addHandler(ch)
# 要打印message的内容 print log info
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
最终程序执行结果:
在当前目录下生成log.log文件,内容如下:
Thu 22 Jun 2017 22:21:44 WARNING example test.py 54 14376 warn message
Thu 22 Jun 2017 22:21:44 ERROR example test.py 55 14376 error message
Thu 22 Jun 2017 22:21:44 CRITICAL example test.py 56 14376 critical message
json模块
详细json资料 :https://docs.python.org/3/library/json.html
Json,全名 JavaScript Object Notation,是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。用于不同编程语言之间传递数据,json数据可以被所有语言读取。
在json模块中有两个我们常用的函数:
dumps & loads
-
dumps 是将 Python 对象编码成 Json字符串,是一种编码的过程
-
loads 是将已编码的 Json 字符串解码为 Python 对象,是一种解码的过程.
序列化和反序列化过程
序列化
import json
dic={'name':'tom','age':23,'sex':'male'}
data=json.dumps(dic)
f=open('序列化对象','w')
f.write(data) #-------------------等价于json.dump(dic,f)
f.close()
反序列化
import json
f=open('序列化对象')
new_data=json.loads(f.read())# 等价于data=json.load(f)
f.close()
print(type(new_data))
json.dumps
import json
dic = {'name':'tom','age':30}
jsondata = json.dumps(dic)
print(jsondata,type(jsondata))
#执行结果:
{"name": "tom", "age": 30} <class 'str'>
Python 编码为 JSON 类型
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int- & float-derived Enums | number |
True | true |
False | false |
None | null |
json.loads
import json
jsondata = '{"name":"tom","age":30}' #这里一定要使用双引号,不然会出错
pydata = json.loads(jsondata)
print(pydata,type(pydata))
#执行结果:
{'name': 'tom', 'age': 30} <class 'dict'>
JSON 编码为 Python类型
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
注意事项
如果文件中数据本来就满足json格式,那么可以直接json.loads出来。不过注意的是json数据中str都必须满足是双引号,不支持单引号。
>>> import json
>>> dic = "{'1':111}"
>>> json.loads(dic) #单引号loads不成功,报错
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
json.loads(dic)
File "C:\Python36\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Python36\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python36\lib\json\decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
>>> d = '{"1":111}'
>>> json.loads(d) #双引号能够loads成功
{'1': 111}
>>>
dumps可以加一些可选参数以便能够输出更友好的内容
dumps:序列化一个对象
sort_keys:根据key排序
indent:以4个空格缩进,输出阅读友好型
ensure_ascii: 可以序列化非ascii码(中文等)
#示例
import json
dic = {"排名": "1", "电影名": "肖申克的救赎", "导演": " 弗兰克·德拉邦特 Frank Darabont", "评分": "9.6", "评价人": "837775"}
t1 = json.dumps(dic)
print(t1)
t2 = json.dumps(dic,indent=None,ensure_ascii=False,sort_keys=True)
print(t2)
t3 = json.dumps(dic,indent=True,ensure_ascii=False,sort_keys=False)
print(t3)
#执行结果:
{"\u6392\u540d": "1", "\u7535\u5f71\u540d": "\u8096\u7533\u514b\u7684\u6551\u8d4e", "\u5bfc\u6f14": " \u5f17\u5170\u514b\u00b7\u5fb7\u62c9\u90a6\u7279 Frank Darabont", "\u8bc4\u5206": "9.6", "\u8bc4\u4ef7\u4eba": "837775"}
{"导演": " 弗兰克·德拉邦特 Frank Darabont", "排名": "1", "电影名": "肖申克的救赎", "评价人": "837775", "评分": "9.6"}
{
"排名": "1",
"电影名": "肖申克的救赎",
"导演": " 弗兰克·德拉邦特 Frank Darabont",
"评分": "9.6",
"评价人": "837775"
}
pickle模块
pickle是用于python数据类型的序列化和反序列化,只能用于python,可能不同python版本之间也会出现不支持,支持python所有数据类型序列化。
pickle用法和json一样,不过文件读写必须是bytes方式(wb,rb等)
序列化
import pickle
dic={'name':'tom','age':23,'sex':'male'}
print(type(dic))#<class 'dict'>
j=pickle.dumps(dic)
print(type(j))#<class 'bytes'>
f=open('序列化对象_pickle','wb') #注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j) #等价于pickle.dump(dic,f)
f.close()
反序列化
import pickle
f=open('序列化对象_pickle','rb')
data=pickle.loads(f.read()) #等价于data=pickle.load(f)
print(data['age'])