python学习——常用模块
在学习常用模块时我们应该知道模块和包是什么,关于模块和包会单独写一篇随笔,下面先来了解有关在python中的几个常用模块。
一、什么是模块
常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。但其实import加载的模块分为四个通用类别:
1. 使用python编写的代码(.py文件)
2.已被编译为共享库或DLL的C或C++扩展
3. 包好一组模块的包
4. 使用C编写并链接到python解释器的内置模块
二、为何要使用模块
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。
在程序开始的地方可以通过 import 这个关键字来导入模块
1 import time
三、常用模块——collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
我们知道tuple
可以表示不变集合,例如,一个点的二维坐标就可以表示成:
1 t1 = (1,2) 2 t2 = (3,4)
但是,看到(1, 2),(3,4),你很难看出这个tuple是用来表示一个坐标的。这时,namedtuple
就派上了用场:
1 from collections import namedtuple 2 3 Point = namedtuple('point',['x','y']) 4 p = Point(1,2) 5 print(p.x,p.y) 6 7 # 输出:1 2 8 9 # 通过nametuple可以用圆心和半径来表示一个圆的面积 10 11 Circle = namedtuple('Circle',['a','b','r'])
2.deque和queue:
deque: 双端队列,可以快速的从两端追加和推出对象
使用list存储数据时,按索引访问元素很快,但是如果列表的元素很多的时候插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低(因为插入和删除元素的时候都会导 致元素的下标向后和向前移动)。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈,deque除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素:
1 from collections import deque 2 q = deque(['x','y','z']) 3 print(q) 4 q.append('a') 5 print(q) 6 q.appendleft('b') 7 print(q) 8 q.pop() 9 print(q) 10 q.popleft() 11 print(q) 12 13 输出: 14 deque(['x', 'y', 'z']) 15 deque(['x', 'y', 'z', 'a']) 16 deque(['b', 'x', 'y', 'z', 'a']) 17 deque(['b', 'x', 'y', 'z']) 18 deque(['x', 'y', 'z'])
deque中的相关方法和list中的方法有很多相似的地方,在这儿就不多说了
queue:和数据结构里面的队列一样,但只能从queue的一端进行修改
1 import queue 2 3 q = queue.Queue() 4 q.put(['x','y','z']) 5 q.put(1) 6 q.put(2) 7 q.put(3) 8 print(q) 9 print(q.qsize()) 10 print(q.get()) 11 print(q.get()) 12 print(q.get()) 13 print(q.get()) 14 print(q.get()) 15 16 #输出: 17 <queue.Queue object at 0x000001B9D1B860F0> 18 4 19 ['x', 'y', 'z'] 20 1 21 2 22 3
所有可以看出queue的FIFO(先进先出)的性质,而deque和queue有个明显的区别就是queue保密性更加好,在deque中如果我们打印deque时我们能看见deque中的每个元素,但是queue就不能看出来,而是返回一个queue对象。
3.Counter: 计数器,主要用来计数 ,Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
1 from collections import Counter 2 3 c = Counter('fashjdklfgjsdjfdslasjfasl') 4 print(c) 5 6 #输出: 7 Counter({'s': 5, 'f': 4, 'j': 4, 'a': 3, 'd': 3, 'l': 3, 'h': 1, 'k': 1, 'g': 1})
4.OrderedDict: 有序字典
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用 OrderedDict
:
1 from collections import OrderedDict 2 3 d = dict([('a',1),('b',2),('c',3)]) 4 print(d) 5 6 od = OrderedDict([('a',1),('b',2),('c',3)]) 7 print(od) 8 9 # 输出: 10 {'a': 1, 'b': 2, 'c': 3} 11 OrderedDict([('a', 1), ('b', 2), ('c', 3)])
由于PyCharm的原因,每次打印的dict都是一样的,但是dict的Key确实是无序的。二变成OrderDict时就是有序的了。
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:
1 from collections import OrderedDict 2 3 od = OrderedDict() 4 od['z'] = 1 5 od['x'] = 2 6 od['y'] = 3 7 print(od) 8 print(od.keys()) 9 # 输出: 10 OrderedDict([('z', 1), ('x', 2), ('y', 3)]) 11 odict_keys(['z', 'x', 'y'])
5.defaultdict: 带有默认值的字典
有如下值集合 [
11
,
22
,
33
,
44
,
55
,
66
,
77
,
88
,
99
,
90.
..],将所有大于
66
的值保存至字典的第一个key中,将小于
66
的值保存至第二个key的值中。
即: {
'k1'
: 大于
66
,
'k2'
: 小于
66
} 若用dict来写应该这样写:
1 lst = [11,22,33,44,55,66,77,88,99,90] 2 my_dict = {} 3 for value in lst: 4 # print(value,end=' ') 5 if value > 66: 6 if 'k1' not in my_dict: 7 my_dict['k1'] = [] 8 my_dict['k1'].append(value) 9 else: 10 my_dict['k1'].append(value) 11 else: 12 if 'k2' not in my_dict: 13 my_dict['k2'] = [] 14 my_dict['k2'].append(value) 15 else: 16 my_dict['k2'].append(value) 17 print(my_dict) 18 19 # 输出:{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}
而用defaultdict是这样的。👇
1 from collections import defaultdict 2 3 lst = [11,22,33,44,55,66,77,88,99,90] 4 my_dict = defaultdict(list) 5 for value in lst: 6 if value > 66: 7 my_dict['k1'].append(value) 8 else: 9 my_dict['k2'].append(value) 10 11 print(my_dict) 12 13 # 输出:defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})
这就是带默认值的字典的好处,当使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
1 from collections import defaultdict 2 3 dd = defaultdict(lambda :'不存在') 4 dd['k1'] = '123' 5 dd['k2'] = '456' 6 print(dd['k1']) 7 print(dd['k2']) 8 print(dd['k3']) 9 10 # 输出: 11 123 12 456 13 不存在
四、常用模块——time模块
在学time模块时,之前我们就知道了有关时间模块的三个方法,如下:
1 import time 2 3 time.time() # 获取从1970年0时0分0秒到现在过去了多少秒 4 time.sleep(1) # 当程序执行到此处时停多少秒(以秒为单位) 5 time.localtime() # 获取本地结构化时间
1.表示时间的3种方式
在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:
(1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型;
(2)格式化的时间字符串(Format String): ‘1999-12-06’;
(3)元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)。
1 %y 两位数的年份表示(00-99) 2 %Y 四位数的年份表示(000-9999) 3 %m 月份(01-12) 4 %d 月内中的一天(0-31) 5 %H 24小时制小时数(0-23) 6 %I 12小时制小时数(01-12) 7 %M 分钟数(00=59) 8 %S 秒(00-59) 9 %a 本地简化星期名称 10 %A 本地完整星期名称 11 %b 本地简化的月份名称 12 %B 本地完整的月份名称 13 %c 本地相应的日期表示和时间表示 14 %j 年内的一天(001-366) 15 %p 本地A.M.或P.M.的等价符 16 %U 一年中的星期数(00-53)星期天为星期的开始 17 %w 星期(0-6),星期天为星期的开始 18 %W 一年中的星期数(00-53)星期一为星期的开始 19 %x 本地相应的日期表示 20 %X 本地相应的时间表示 21 %Z 当前时区的名称 22 %% %号本身 23 24 python中时间日期格式化符号:
小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
几种时间格式之间的转化
1 #时间戳-->结构化时间 2 #time.gmtime(时间戳) #UTC时间,与英国伦敦当地时间一致 3 #time.localtime(时间戳) #当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间 4 5 import time 6 7 time.time() 8 Out[3]: 1542104643.2747378 9 10 time.gmtime(1800000000) 11 Out[4]: time.struct_time(tm_year=2027, tm_mon=1, tm_mday=15, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=15, tm_isdst=0) 12 13 time.localtime(1800000000) 14 Out[5]: time.struct_time(tm_year=2027, tm_mon=1, tm_mday=15, tm_hour=16, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=15, tm_isdst=0) 15 16 time.localtime() 17 Out[6]: time.struct_time(tm_year=2018, tm_mon=11, tm_mday=13, tm_hour=18, tm_min=25, tm_sec=28, tm_wday=1, tm_yday=317, tm_isdst=0) 18 19 time_tuple = time.localtime(1800000000) 20 time.mktime(time_tuple) 21 22 Out[8]: 1800000000.0 23 24 #结构化时间-->字符串时间 25 #time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间 26 27 time.strptime("2018-11-11","%Y-%m-%d") 28 29 Out[12]: time.struct_time(tm_year=2018, tm_mon=11, tm_mday=11, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=315, tm_isdst=-1) 30 31 time.strptime("10/01/2018","%m/%d/%Y") 32 33 Out[13]: time.struct_time(tm_year=2018, tm_mon=10, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=274, tm_isdst=-1)
结构化时间:
1 #结构化时间 --> %a %b %d %H:%M:%S %Y串 2 #time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串 3 4 time.asctime(time.localtime(1800000000)) 5 Out[14]: 'Fri Jan 15 16:00:00 2027' 6 time.asctime() 7 Out[15]: 'Tue Nov 13 18:41:45 2018' 8 9 #时间戳 --> %a %b %d %H:%M:%S %Y串 10 #time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串 11 12 time.ctime() 13 Out[16]: 'Tue Nov 13 18:41:53 2018' 14 time.ctime(1800000000) 15 Out[17]: 'Fri Jan 15 16:00:00 2027'
1 import time 2 3 true_time = time.mktime(time.strptime('2018-11-11 00:00:00', '%Y-%m-%d %H:%M:%S')) 4 time_now = time.mktime(time.strptime('2018-11-12 00:00:00', '%Y-%m-%d %H:%M:%S')) 5 dif_time = time_now - true_time 6 struct_time = time.gmtime(dif_time) 7 print('过去了{}年{}月{}天{}小时{}分钟{}秒'.format(struct_time.tm_year-1970, struct_time.tm_mon-1, \ 8 struct_time.tm_mday-1, struct_time.tm_hour,struct_time.tm_min, struct_time.tm_sec)) 9 10 # 输出:过去了0年0月1天0小时0分钟0秒
五、常用模块——random模块
1 import random 2 #随机小数 3 random.random() # 大于0且小于1之间的小数 4 # 输出:0.30352703804970593 5 random.uniform(1,3) #大于1小于3的小数 6 # 输出:6.574842548037611 7 8 #随机整数 9 random.randint(1,10) # 大于等于1且小于等于5之间的整数 10 # 输出:1 11 random.randint(1,10) 12 # 输出:3 13 random.randint(1,10) 14 # 输出:1 15 random.randint(1,10) 16 # 输出:7 17 random.randint(1,10) 18 # 输出:2 19 random.randint(1,10) 20 # 输出:6 21 random.randrange(1,10,2) # 大于等于1且小于10之间的奇数 22 # 输出:7 23 24 #随机选择一个返回 25 random.choice(['a',1,2,3,['b','c'],(4,5),{6,7,8},{'d':9,'e':10}]) 26 # 输出:['b', 'c'] 27 #随机选择多个返回,返回的个数为函数的第二个参数 28 random.sample(['a',1,2,3,['b','c'],(4,5),{6,7,8},{'d':9,'e':10}],5) #列表元素任意5个组合 29 # 输出:[3, ['b', 'c'], 'a', 2, {'d': 9, 'e': 10}] 30 31 32 #打乱列表顺序 33 lst = [1,2,3,4,5,6,7,8,9] 34 random.shuffle(lst) # 打乱次序 35 lst 36 # 输出 : [3, 2, 4, 8, 9, 1, 6, 5, 7] 37 random.shuffle(lst) 38 lst 39 # 输出 : [1, 2, 7, 6, 8, 4, 5, 9, 3]
练习————生成随机验证码
1 import random 2 3 def v_code(): 4 code = '' 5 for i in range(5): 6 num=random.randint(0,9) 7 alf=chr(random.randint(65,90)) 8 add=random.choice([num,alf]) 9 code="".join([code,str(add)]) 10 11 return code 12 13 print(v_code()) 14 15 # 输出: 16 2T3J9 17 2UHB9 18 HWR71 19 Q7I7W 20 Y94CT
六、常用模块——sys模块
sys模块是与python解释器交互的一种接口
1 sys.argv #命令行参数List,第一个元素是程序本身路径 2 sys.exit(n) #退出程序,正常退出时exit(0),错误退出sys.exit(1) 3 sys.version #获取Python解释程序的版本信息 4 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 5 sys.platform #返回操作系统平台名称
七 、常用模块——os模块
os模块是与操作系统交互的一个接口
1 os.makedirs('dirname1/dirname2') 可生成多层递归目录 2 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 3 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname 4 os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 5 os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 6 os.remove() 删除一个文件 7 os.rename("oldname","newname") 重命名文件/目录 8 os.stat('path/filename') 获取文件/目录信息 9 10 os.system("bash command") 运行shell命令,直接显示 11 os.popen("bash command).read() 运行shell命令,获取执行结果 12 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 13 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd 14 15 16 os.path 17 os.path.abspath(path) 返回path规范化的绝对路径 18 os.path.split(path) 将path分割成目录和文件名二元组返回 19 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 20 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 21 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False 22 os.path.isabs(path) 如果path是绝对路径,返回True 23 os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False 24 os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False 25 os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 26 os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 27 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 28 os.path.getsize(path) 返回path的大小
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)是创建时间(详细信息参见平台的文档)。
1 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" 2 os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n" 3 os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: 4 os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
未完待续!