Python学习(十) —— 常用模块

时间:2022-11-26 14:41:14

一、collections模块

  在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

  1.namedtuple:生成可以使用名字来访问元素内容的tuple

  2.deque:双端队列,可以快速的从另外一侧追加和推测对象

  3.Counter:计数器,主要用来计数

  4.OrderedDict:有序字典

  5.defaultdict:带有默认值的字典

 

  namedtuple

from collections import namedtuple
Point = namedtuple('Point',['x','y'])
p = Point(1,2)
print(p.x) #1
print(p.y) #2

  deque

  list存储数据,按索引访问元素很快,但是插入和删除元素很慢,因为list是线性存储

  deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈

from collections import deque
q = deque(['a','b','c'])
q.append('x')
q.appendleft('y')
print(q) #deque(['y', 'a', 'b', 'c', 'x'])
q.pop()
print(q) #deque(['y', 'a', 'b', 'c'])
print(q.popleft()) #y

  OrderedDict

  dict的key是无序的,OrderedDict的key是有序的

from collections import OrderedDict
od = OrderedDict([('a',1),('b',2),('c',3)])
print(od) #OrderedDict([('a', 1), ('b', 2), ('c', 3)]) od1 = OrderedDict()
od1['k1'] = 'x'
od1['k2'] = 'y'
od1['k3'] = 'z'
print(od1.keys()) #odict_keys(['k1', 'k2', 'k3'])
print(od1) #OrderedDict([('k1', 'x'), ('k2', 'y'), ('k3', 'z')])

  defaultdict:含有默认值的字典

  使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

from collections import defaultdict
dedic = defaultdict(lambda :3)
dedic['k1'] = 'a'
dedic['k2']
print(dedic['k1']) #a
print(dedic['k2']) #

  Counter

  Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

from collections import Counter
c = Counter('abcdeabcdabcaba')
print(c) #Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

二、时间模块(time)

  表示时间的三种方式:时间戳,元组(struct_time),格式化的时间字符串

  1.时间戳(timestamp):时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。类型是float

  2.格式化的时间字符串(Format String):'1992-12-06'

%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

Python中时间日期格式化符号

  3.元组(struct_time):struct_time元组共有九个元素:(年,月,日,时,分,秒,一年中第几天等

索引(Index) 属性(Attribute) 值(Values)
0 tm_year(年) 比如2011
1 tm_mon(月) 1 - 12
2 tm_mday(日) 1 - 31
3 tm_hour(时) 0 - 23
4 tm_min(分) 0 - 59
5 tm_sec(秒) 0 - 60
6 tm_wday(weekday) 0 - 6(0表示周一)
7 tm_yday(一年中的第几天) 1 - 366
8 tm_isdst(是否是夏令时) 默认为0

几种格式之间的转换

Python学习(十) —— 常用模块

  时间戳——>结构化时间:time.localtime()(当地时间,北京时间),time.gmtime()(UTC时间,伦敦时间)

  结构化时间——>时间戳:time.mktime()

  结构化时间——>字符串时间:time.strftime(显示格式,格式化时间)

  字符串时间——>结构化时间:time.strptime(字符串时间,字符串对应格式)

import time
# Timestamp ——> struct_time
print(time.localtime(0)) #北京时间,默认是1970-01-01 08:00:00
print(time.gmtime(0)) #伦敦时间,默认是1970-01-01 00:00:00
print(time.localtime()) #当前时间的结构化显示
print(time.gmtime()) #当前的伦敦时间的结构化显示 #stuct_time ——> Timestamp
st_time = time.localtime()
print(time.mktime(st_time)) #结构化时间转化时间戳 #stuct_time ——> Format string
st_time = time.localtime()
print(time.strftime('%Y-%m-%d',st_time)) #结构化时间转化字符串时间
print(time.strftime('%Y-%m-%d %X')) #Format string ——> stuct_time
print(time.strptime('2017-11-04','%Y-%m-%d')) #字符串时间转化结构化时间

Python学习(十) —— 常用模块

  time.asctime(格式化时间),如果不传参数,直接返回当前时间的格式化串

  time.ctime(时间戳),如果不传参数,直接返回当前时间的格式化串

#结构化时间转字符串格式时间
print(time.asctime())
print(time.asctime(time.localtime(100000000))) #时间戳转字符串格式时间
print(time.ctime())
print(time.ctime(30000000))

  计算时间差

#计算时间差
import time
true_time = time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
time_now = time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S'))
dif_time = time_now - true_time
struct_time = time.gmtime(dif_time)
print('过去了%d年%d月%d日%d时%d分%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,struct_time.tm_mday-1,struct_time.tm_hour,struct_time.tm_min,struct_time.tm_sec))

三、sys模块

  sys模块是与python解释器交互的一个接口

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1)
sys.version 获取Python解释程序的版本信息
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称

四、random模块

  产生随机数

  random.random():产生0-1的随机消失

  random.uniform(n,m):产生n-m的随机小数

  random.randint(n,m):产生[n,m]的随机整数

  random.randrange(n,m):产生[n,m)的随机整数,可加步长

  random.choice(可迭代对象):从可迭代对象随机选择一个元素

  random.sample(可迭代对象,n),从可迭代对象选择n个元素

  random.shuffle(可迭代对象),打乱顺序,用于洗牌,排序计算

import random
#产生随机小数
print(random.random())
print(random.uniform(1,10))
#产生随机整数
print(random.randint(0,1))
print(random.randrange(1,100,2))
#随机选择
print(random.choice([1,2,3,4,5,6]))
print(random.sample(['a','b','c','d',1,2,3,4],3))
#打乱顺序
l = [1,2,3,4,5,6]
random.shuffle(l)
print(l)
import random
l = []
for i in range(6):
alpha_up = chr(random.randint(65,90))
alpha_low = chr(random.randint(97,122))
num = str(random.randint(0,9))
ret = random.choice([alpha_up,alpha_low,num])
l.append(ret)
print(''.join(l))

生成随机验证码

五、os模块

  os模块是与操作系统交互的一个接口

  os.getcwd():获取当前工作目录,即当前python文件的绝对路径

  os.chdir('dirname'):改变当前脚本工作目录;相当于shell下的cd

  os.curdir:返回当前目录(.)

  os.pardir:返回上级目录(..)

  os.makedirs('name1/name2'):可生成多层递归目录

  os.mkdir():生成单级目录

  os.removedies('文件绝对路径'):若目录为空,则删除,若上级也为空,也一并删除,依此类推

  os.rmdir():删除单级空目录

  os.listdir('dirname'):列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

  os.remove(‘文件路径’):删除文件

  os.rename(旧,新):重命名文件/目录

  os.stat('path/filename'):获取文件/目录信息

  os.sep:输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"

  os.linesep:输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"

  os.pathsep:输出用于分割文件路径的字符串 win下为;,Linux下为:

  os.name:输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

  os.system("bash command"):运行shell命令,直接显示

  os.popen('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所指向的文件或者目录的最后修改时间

  os.path.getsize(path):返回path的大小

  注意:os.stat('path/filename')  获取文件/目录信息 的结构说明

stat 结构:
st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。
st_uid: 所有者的用户ID。
st_gid: 所有者的组ID。
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
st_atime: 上次访问的时间。
st_mtime: 最后一次修改的时间。
st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。

stat结构说明

六、序列化模块

  序列化:将列表、元组、字典转换成一个字符串的过程叫做序列化。

  序列化的目的:1.以某种存储形式使自定义对象持久化;

         2.将对象从一个地方传递到另一个地方;

         3.使程序更具维护性。

Python学习(十) —— 常用模块

  json

  json模块提供了四个功能:dumps、loads、dump、load

import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #转换成字符串数据类型
print(repr(str_dic),type(str_dic)) #'{"k1": "v1", "k2": "v2", "k3": "v3"}' <class 'str'> dic2 = json.loads(str_dic) #转化成字典
print(repr(dic2),type(dic2)) #{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} <class 'dict'> lis_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_lic = json.dumps(lis_dic) #转化成字符串数据类型
print(repr(str_lic),type(str_lic)) #'[1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]' <class 'str'>
lic = json.loads(str_lic) #转换成列表
print(repr(lic),type(lic)) #[1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}] <class 'list'>
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f) #转换成字符串写入文件
f.close() f = open('json_file')
dic2 = json.load(f) #读取文件转换成字典
f.close()
print(repr(dic2),type(dic2)) #{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} <class 'dict'>

  pickle

  python专有的和其它语言不兼容,可以序列化任何数据类型,结果是bytes,用pickle序列化的数据,反序列化也必须用pickle

  pickle模块提供了四个功能:dumps、loads、dump、load

  shelve

  python专有,只提供一个open方法,shelve.open(文件名)拿到一个文件句柄,这个文件句柄就可以当作字典操作,用key来访问

import shelve
f = shelve.open('shelve_file')
f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据
f.close() f1 = shelve.open('shelve_file')
existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing) #{'int': 10, 'float': 9.5, 'string': 'Sample data'}

  shelve不支持多人同时写,支持多人同事读,如果想用只读打开,那么设置flag = 'True'

  正常情况下shelve打开的文件句柄感知不到值的修改,设置writeback = True就可以保存修改内容了

import shelve
f = shelve.open('shelve_file')
f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据
f.close() f1 = shelve.open('shelve_file',writeback = 'True') #writeback = 'True'可以保存修改的内容
print(f1['key']) #{'int': 10, 'float': 9.5, 'string': 'Sample data'}
f1['key']['new_value'] = 'this was not here before' #增加new_value
f1.close() f = shelve.open('shelve_file',flag='r')
print(f['key']) #{'int': 10, 'float': 9.5, 'string': 'Sample data', 'new_value': 'this was not here before'}
f.close()

七、异常

  程序中难免会出现错误,错误分两种:语法错误,逻辑错误

  异常就是程序运行时发生错误的信号,在python中不同类型的异常可以用不同类型去标识,一个异常标识一种错误

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError

更多异常

  处理异常

  if判断式

  1.if判断式的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误你需要写重复的if来进行处理。

  2.在你的程序中频繁的写与程序本身无关,与异常处理有关的if,会使得你的代码可读性极其的差

  3.if是可以解决异常的,只是存在1,2的问题,所以,千万不要妄下定论if不能用来异常处理。

  try...except...

try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑

  多分支

s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)

  万能异常:Exception

s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)

  多分支+Exception

s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)

  异常的其它机构:else(没有触发异常才会执行的代码),finally(不管有没有触发异常,都会执行的代码,遇到return,也会执行这段代码)

s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
#except Exception as e:
# print(e)
else:
print('try内代码块没有异常则执行我')
finally:
print('无论异常与否,都会执行该模块,通常是进行清理工作')

  主动触发异常:raise TypeError('说明')

try:
raise TypeError('类型错误')
except Exception as e:
print(e)

  断言:assert

# assert 条件
assert 1 == 1
assert 1 == 2

  try..except的方式比较if的方式的好处

try..except这种异常处理机制就是取代if那种方式,让你的程序在不牺牲可读性的前提下增强健壮性和容错性
异常处理中为每一个异常定制了异常类型(python中统一了类与类型,类型即类),对于同一种异常,一个except就可以捕捉到,可以同时处理多段代码的异常(无需‘写多个if判断式’)减少了代码,增强了可读性 使用try..except的方式
1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;