第九章 常用模块
Posted gnaix
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九章 常用模块相关的知识,希望对你有一定的参考价值。
第九章 常用模块
1.模块介绍
什么是模块:
模块就是我们通常说的py文件(因此写python程序的时候不要命名为模块的名称),模块是写好了但不直接使用的功能
为什么这些模块中提供的方法 不能像print这些内置函数一样直接使用呢?
是因为如果所有的模块都是执行python程序直接导入了,会非常占用内存空间的
常见导入模块的方法
1.import time
2.from time import sleep
模块的分类:
内置模块
扩展模块 https://pypi.org
自定义模块
2.扩展数据类型模块collections
‘‘‘ collections 英 [k?‘lek??nz] 美 [k?‘lek??nz] n.收藏品;收集( collection的名词复数 );作品集;募集的款项 在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。 ‘‘‘
from collections import namedtuple # 1- namedtuple: 生成可以使用名字来访问元素内容的tuple(可命名元组) # 1) 表示扑克牌 Card = namedtuple(‘card‘, [‘rank‘, ‘suit‘]) c = Card(‘2‘, ‘红心‘) print(Card) # <class ‘__main__.card‘> print(c) # card(rank=‘2‘, suit=‘红心‘) # 2) 表示坐标 Point = namedtuple(‘Point‘, [‘x‘, ‘y‘]) p = Point(1, 2) print(p.x) # 1 print(p.y) # 2
# 2- deque: 双端队列,可以快速的从另外一侧追加和推出对象 # 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。 # deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈: from collections import deque q = deque([‘a‘, ‘b‘, ‘c‘]) q.append(‘x‘) print(q) # deque([‘a‘, ‘b‘, ‘c‘, ‘x‘]) q.appendleft(‘y‘) print(q) # deque([‘y‘, ‘a‘, ‘b‘, ‘c‘, ‘x‘]) q.pop() print(q) # deque([‘y‘, ‘a‘, ‘b‘, ‘c‘]) # pop不添加参数,默认删除最后一个元素 q.popleft() print(q) # deque([‘a‘, ‘b‘, ‘c‘])
# 3- Counter: 计数器,主要用来计数 ##########用处不多 # Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。 from collections import Counter s = Counter(‘asdfasdfasdfasdfasdfasdf‘) print(s) # Counter({‘a‘: 6, ‘s‘: 6, ‘d‘: 6, ‘f‘: 6})
# 4- OrderedDict: 有序字典 # 使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。 # 如果要保持Key的顺序,可以用OrderedDict: import collections d = collections.OrderedDict() print(d) # OrderedDict() d[‘电脑‘] = 10000 d[‘苹果‘] = 10 print(d) # OrderedDict([(‘电脑‘, 10000), (‘苹果‘, 10)]) for i in d: print(i, d[i]) # 电脑 10000 # 苹果 10 # 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序: d = collections.OrderedDict() d[‘x‘] = 1 d[‘z‘] = 2 d[‘y‘] = 3 print(d) # OrderedDict([(‘x‘, 1), (‘z‘, 2), (‘y‘, 3)])
# 5- defaultdict: 带有默认值的字典 # 常见使用方法 from collections import defaultdict my_dict = defaultdict(list) print(my_dict) # defaultdict(<class ‘list‘>, {}) my_dict[‘a‘].append(1) print(my_dict) # defaultdict(<class ‘list‘>, {‘a‘: [1]}) my_dict[‘a‘].append(2) print(my_dict) # defaultdict(<class ‘list‘>, {‘a‘: [1, 2]}) my_dict[‘b‘].append(2) print(my_dict) # defaultdict(<class ‘list‘>, {‘a‘: [1, 2], ‘b‘: [2]}) my_dict[‘c‘] = 10 print(my_dict) # defaultdict(<class ‘list‘>, {‘a‘: [1, 2], ‘b‘: [2], ‘c‘: 10}) # 例; # 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。 # 即: {‘k1‘: 大于66 , ‘k2‘: 小于66} # values = [11, 22, 33,44,55,66,77,88,99,90] # 1) 普通方法 my_dict = {} values = [11, 22, 33,44,55,66,77,88,99,90] for value in values: if value>66: if my_dict.get(‘k1‘): my_dict[‘k1‘].append(value) else: my_dict[‘k1‘] = [value] else: if my_dict.get(‘k2‘): my_dict[‘k2‘].append(value) else: my_dict[‘k2‘] = [value] print(my_dict) # {‘k2‘: [11, 22, 33, 44, 55, 66], ‘k1‘: [77, 88, 99, 90]} # 2) 默认字典方法 my_dict = defaultdict(list) for value in values: if value>66: my_dict[‘k1‘].append(value) else: my_dict[‘k2‘].append(value) print(my_dict) # defaultdict(<class ‘list‘>, {‘k2‘: [11, 22, 33, 44, 55, 66], ‘k1‘: [77, 88, 99, 90]})
3.时间模块time
表示时间的三种方式
在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:
(1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
# 1- 时间戳时间的开始为 英国伦敦时间 1970 1 1 0 0 0 # 相当于 北京时间 1970 1 8 0 0 0 import time print(time.time()) # 1525680508.1982615
(2)格式化的时间字符串(Format String): ‘1999-12-06’
# 2- 格式化时间 用字符串表示的时间 # str-format-time print(time.strftime(‘%H:%M:%S‘)) # 16:10:03 print(time.strftime(‘%Y-%m-%d %H:%M:%S‘)) # 2018-05-07 16:10:55 # %y 两位数的年份表示(00-99) print(time.strftime(‘%y‘)) # 18 # %Y 四位数的年份表示(000-9999) print(time.strftime(‘%Y‘)) # 2018 # %m 月份(01-12) print(time.strftime(‘%m‘)) # 05 # %d 月内中的一天(0-31) print(time.strftime(‘%d‘)) # 07 # %H 24小时制小时数(0-23) print(time.strftime(‘%H‘)) # 16 # %I 12小时制小时数(01-12) print(time.strftime(‘%I‘)) # 04 # %M 分钟数(00=59) print(time.strftime(‘%M‘)) # 16 # %S 秒(00-59) print(time.strftime(‘%S‘)) # 55 # %a 本地简化星期名称 print(time.strftime(‘%a‘)) # Mon # %A 本地完整星期名称 print(time.strftime(‘%A‘)) # Monday # %b 本地简化的月份名称 print(time.strftime(‘%b‘)) # May # %B 本地完整的月份名称 print(time.strftime(‘%B‘)) # May # %c 本地相应的日期表示和时间表示 print(time.strftime(‘%c‘)) # Mon May 7 16:18:08 2018 # %j 年内的一天(001-366) print(time.strftime(‘%j‘)) # 127 # %p 本地A.M.或P.M.的等价符 print(time.strftime(‘%p‘)) # PM # %U 一年中的星期数(00-53)星期天为星期的开始 print(time.strftime(‘%U‘)) # 18 # %w 星期(0-6),星期天为星期的开始 print(time.strftime(‘%w‘)) # 1 # %W 一年中的星期数(00-53)星期一为星期的开始 print(time.strftime(‘%W‘)) # 19 # %x 本地相应的日期表示 print(time.strftime(‘%x‘)) # 05/07/18 # %X 本地相应的时间表示 print(time.strftime(‘%X‘)) # 16:20:13 # %Z 当前时区的名称 print(time.strftime(‘%Z‘)) # %% %号本身 print(time.strftime(‘%%‘)) # % 没有其他输出,只打印%
(3)元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
import time print(time.localtime()) # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=7, tm_hour=16, tm_min=28, tm_sec=46, tm_wday=0, tm_yday=127, tm_isdst=0) # 索引(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
(4) 常见时间格式
import time # 时间戳 print(time.time()) # 1525682097.3387372 # 时间字符串 print(time.strftime(‘%Y-%m-%d %X‘)) # 2018-05-07 16:35:39 # 时间元组:localtime将一个时间戳转换为当前时区的struct_time print(time.localtime()) # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=7, tm_hour=16, tm_min=35, tm_sec=39, tm_wday=0, tm_yday=127, tm_isdst=0) # 小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
(5) 常见时间格式之间的转化
# 1- 时间戳与时间元组之间的转化 import time # 时间戳 --> 时间元组 print(type(time.time())) # <class ‘float‘> # 1525683615.8126261 print(time.localtime(1525683615.8126261)) # 根据当地时区,获取时间元组 # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=7, tm_hour=17, tm_min=0, tm_sec=15, tm_wday=0, tm_yday=127, tm_isdst=0) print(time.gmtime(1525683615.8126261)) # 根据格林威治时间,获取时间元组 # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=7, tm_hour=9, tm_min=0, tm_sec=15, tm_wday=0, tm_yday=127, tm_isdst=0) # 时间元组 --> 时间戳 time_tuple = time.localtime(1525683615.8126261) print(time.mktime(time_tuple)) # 1525683615.0
# 2- 时间元组与时间字符串之间的转化 import time # 时间元组 --> 时间字符串 time_tuple = time.localtime(1525683615.8126261) print(time.strftime(‘%Y-%m-%d %X‘, time_tuple)) # 2018-05-07 17:00:15 # 时间字符串 --> 时间元组 time_str = ‘2018-05-07 17:00:15‘ print(time.strptime(time_str, ‘%Y-%m-%d %X‘)) # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=7, tm_hour=17, tm_min=0, tm_sec=15, tm_wday=0, tm_yday=127, tm_isdst=-1)
# 3- 时间戳、时间字符串之间的转化 import time # 时间字符串 --> 时间元组 --> 时间戳 time_str = ‘2018-05-07 17:00:15‘ time_tuple = time.strptime(time_str, ‘%Y-%m-%d %X‘) time_stamp = time.mktime(time_tuple) print(time_stamp) # 1525683615.0 # 时间戳 --> 时间元组 --> 时间字符串 time_stamp = 1525683615.0 time_tuple = time.localtime(time_stamp) time_str = time.strftime(‘%Y-%m-%d %X‘, time_tuple) print(time_str) # 2018-05-07 17:00:15
4.random随机模块
‘‘‘ random 英 [?r?nd?m] 美 [?r?nd?m] adj.随机的;任意的;胡乱的 n.随意;偶然的行动 应用:发红包,数学建模问题 ‘‘‘ import random # 1- 随机小数 # 大于0且小于1之间的小数 print(random.random()) # 0.09175640794946482 # 大于1小于3的小数 print(random.uniform(1,3)) # 1.1317431420218869 # 2- 随机整数 # 去随机整数,顾头顾尾 # 大于等于1且小于等于5之间的整数 print(random.randint(1,5)) # 5 # 大于等于1且小于10之间的奇数 print(random.randrange(1,10,2)) # 7 # 1 5 9 随机取一个数 print(random.randrange(1,11,4)) # 3- 随机序列元素 # 1) 随机选择一个返回 print(random.choice([1,‘2‘,[3, 4]])) # [3, 4] # 返回元组中的一个随机元素 print(random.choice((1,2,4))) # 1 # 返回字符串中的一个随机元素 print(random.choice(‘abcd‘)) # a # ******注意:字典类型不支持索引,所以random不能对集合进行操作 print(random.choice({1:‘x‘, 2:‘y‘, 3:‘z‘})) # return seq[i] # KeyError: 0 import collections d = collections.OrderedDict() d[‘x‘] = 1 d[‘y‘] = 2 d[‘z‘] = 3 print(random.choice(d)) # return seq[i] # KeyError: 0 # ******注意:集合类型不支持索引,所以random不能对集合进行操作 # set = {1,2,3} # print(random.choice(set)) # return seq[i] # TypeError: ‘set‘ object does not support indexing # 2) 随机选择多个元素,返回的个数为函数的第二个参数 print(random.sample([1,‘2‘,[3, 4]], 2)) # [‘2‘, [3, 4]] # 4- 四位手机随机验证码 s = ‘‘ for i in range(4): s += str(random.randint(0,9)) print(s) # 4151 # 5- 电脑上,6位随机验证码 import random id = ‘‘ for i in range(6): # A-Z num = random.randint(65,90) alpha1 = chr(num) # a-z num = random.randint(97,122) alpha2 = chr(num) num3 = str(random.randint(0,9)) print(alpha1, alpha2, num3) # 随机选择一个返回 s = random.choice([alpha1, alpha2, num3]) id += s print(id) # D b 2 # K i 7 # S y 3 # P k 8 # Q n 5 # T s 0 # 27y8ns
5.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 输出用于分割文件路径的字符串 win下为;,Linux下为: # os.name 输出字符串指示当前使用平台。win->‘nt‘; Linux->‘posix‘ ####和执行系统命令相关 # os.system -- exec # os.popen -- eval # os.system("bash command") 运行shell命令,直接显示 # os.popen("bash command).read() 运行shell命令,获取执行结果 # os.environ 获取系统环境变量 # ####跟路径相关 # os.path # 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的大小
6.sys解释器相关模块
# sys模块是与python解释器交互的一个接口 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称
7.re正则相关模块
7-1.正则表达式
正则表达式就是匹配字符串内容的一种规则
官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
测试工具http://tool.chinaz.com/regex/
字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 字符分为很多类,比如数字、字母、标点等等。 假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。 ***注意:遇到1-5类似的范围的时候,要按照ascii的顺序,3-1是有问题的
正则 |
说明 |
[0123456789] |
0到9,匹配一个数字 |
[0-9] |
同上 |
[a-z] |
匹配一个小写字母 |
[A-Z] |
匹配一个大写字母 |
[a-zA-Z] |
匹配一个字母 |
[0-9a-zA-Z] |
匹配一个字母或数字 |
字符:
元字符 | 匹配内容 |
. | 匹配除换行符以外的任意字符 |
\\w | 匹配字幕或者数字或下划线 |
\\s | 匹配任意的空白符 |
\\d | 匹配数字 |
\\n | 匹配一个换行符 |
\\t | 匹配一个制表符 |
\\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\\W | 匹配非字母或数字或下划线 |
\\D | 匹配非数字 |
\\S | 匹配非空白符 |
a|b | 匹配字符a或字符b |
注意 | 正则表达式是按照从左到右依次匹配的 |
ABC|ABCD ABC | |
ABCD|ABC ABCD | |
() | 匹配括号内的表达式,也表示一个组 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中字符的所有字符 |
注意: import re s = ‘abcdabc‘ print(re.findall(‘abc|abcd‘, s)) # [‘abc‘, ‘abc‘] print(re.findall(‘abcd|abc‘, s)) # [‘abcd‘, ‘abc‘]
量词:
贪婪匹配 | 非贪婪匹配 | ||
量词 | 用法说明 | 量词 | 用法说明 |
* | 重复零次或更多次 | *? | 重复任意次,但尽可能少重复 |
+ | 重复一次或更多次 | +? | 重复一次或更多次,但尽可能少重复 |
? | 重复零次或一次 | ?? | 重复零次或一次,但尽可能少重复 |
{n} | 重复n次 | ||
{n,} | 重复n次或更多次 | {n,}? | 重复n次或更多次,但尽可能少重复 |
{n,m} | 重复n到m次 | {n,m}? | 重复n到m次,但尽可能少重复 |
注意 |
*,+,?等都是贪婪匹配,也就是尽可能匹配, 后面加?就使其变成惰性匹配 |
# 贪婪匹配 # 正则表达式中的所有量词,都会尽量多的为你匹配 # + 表示匹配一次或多次 # 为什么出现 # 算法:回溯算法 尽量多匹配,直到匹配不到 s = ‘李杰和李莲英和李二棍子‘ import re print(re.findall(‘李.?‘, s)) # [‘李杰‘, ‘李莲‘, ‘李二‘] print(re.findall(‘李.*‘, s)) # [‘李杰和李莲英和李二棍子‘] print(re.findall(‘李.+‘, s)) # [‘李杰和李莲英和李二棍子‘] print(re.findall(‘李.{1,2}‘, s)) # [‘李杰和‘, ‘李莲英‘, ‘李二棍‘] # 注意:前面的 *, +,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配 print(re.findall(‘李.*?‘, s)) # [‘李‘, ‘李‘, ‘李‘]
转义符\\
正则 | 待匹配字符 | 说明 |
\\d | \\d | 匹配一个数字 |
\\\\d | ‘\\d‘ | 匹配‘\\d‘字符 |
‘\\\\\\\\d‘ | ‘\\\\d‘ | 匹配‘\\\\d‘字符 |
r‘\\\\d‘ | ‘\\\\d‘ | 匹配‘\\\\d‘字符 |
7-2.re模块
import re s = ‘1234eva12341234 egon1234 yuan‘ # 1- findall 找所有 # 返回所有满足匹配条件的结果,放在列表里 s = ‘1234eva12341234 egon1234 yuan‘ ret = re.findall(‘\\d+‘, s) print(ret) # [‘1234‘, ‘12341234‘, ‘1234‘] # 2- search找第一个 # 返回的值不是一个直接的结果,而是一个内存地址 需要使用.group()取值 # 如果匹配不上 返回None 就不能group s = ‘1234eva12341234 egon1234 yuan‘ ret = re.search(‘\\d+‘, s) print(ret) # <_sre.SRE_Match object; span=(0, 4), match=‘1234‘> if ret:print(ret.group()) # 常用写法 # 1234 # 3- split 按照已匹配的字符,分割字符串 s = ‘1234eva12341234 egon1234 yuan‘ ret = re.split(‘[24]‘, s) print(s) print(ret) # 1234eva12341234 egon1234 yuan # [‘1‘, ‘3‘, ‘eva1‘, ‘3‘, ‘1‘, ‘3‘, ‘ egon1‘, ‘3‘, ‘ yuan‘] # 4- sub 按照参数替换,参数表示替换几个 s = ‘1234eva12341234 egon1234 yuan‘ ret = re.sub(‘\\d‘, ‘-‘, s, 3) print(ret) # ---4eva12341234 egon1234 yuan # 5- subn 替换匹配对象,有多少次替换多少个 # 返回值是一个元组,第一个元素是替换的结果,第二个元素是替换的次数 s = ‘1234eva12341234 egon1234 yuan‘ ret = re.subn(‘\\d‘, ‘-‘, s) print(ret) # (‘----eva-------- egon---- yuan‘, 16) # 6- compile 将正则表达式编译成为一个 正则表达式对象 s = ‘1234eva12341234 egon1234 yuan‘ obj = re.compile(‘\\d{3}‘) # 规则表示要匹配的是3个数字 ret = re.findall(obj, s) print(ret) # [‘123‘, ‘123‘, ‘412‘, ‘123‘] # 7- finditer 返回一个存放匹配结果的迭代器 s = ‘1234eva12341234 egon1234 yuan‘ ret = re.finditer(‘\\d+‘, s) print(ret) # <callable_iterator object at 0x000001DFD2E7E710> print(next(ret).group()) # 1234 print(next(ret).group()) # 12341234 print(next(ret).group()) # 1234