【3】python之模块及第三方库
Python有非常丰富和强大的标准库和第三方库,我们称之为模块。
a:标准库(内置模块)
b:开源模块(第三方库)
c:自定义模块
1、定义
模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件
ps: 包:用来从逻辑上组织模块代码,本质是一个目录(必须带有一个__init__.py文件)
2、模块导入方法
使用import导入模块
导入模块
import module1_name
导入多个模块
import module1_name,module2_name
导入所有模块
from module import *
导入模块并改名
from module import logger as logger_import
模块import的本质
导入模块就是解释python文件
ps: 导入包就是解释__init__.py文件
import
解释模块所有代码,赋值给模块名变量
调用需加前缀模块名
from import
打开模块,解释所需部分代码
调用不需加前缀模块名
3、模块路径
Python标准库常用存储路径:
'D:\\python\\untitled1\\venv\\lib
Python第三方库常用存储路径:
'D:\\python\\untitled1\\venv\\lib\\site-packages
导入模块,一般路径设置为将所需路径追加到环境变量路径中,sys.append()追加到最后,sys.insert()追加到第一个
sys.path可以获得环境变量路径
os.path可以获得当前文件路径
os.path.abspath(__file__)#获取当前文件路径
os.path.dirname(os.path.abspath(__file__))#获取当前文件的目录名
1 import sys,os 2 3 print(sys.path)#环境变量路径 4 print(os.path.abspath(__file__))#获取当前文件路径 5 print(os.path.dirname(os.path.abspath(__file__)))#获取当前文件的目录名 6 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 7 #sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 8 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 9 print(sys.path)#环境变量路径
4、自定义模块
1 2 import getpass 3 4 _username = "alex" 5 _password = "abc123" 6 7 username=input("username:") 8 password=input("password:") 9 #password=getpass.getpass("password:") jia mi 10 11 if _username==username and _password==password: 12 print("wlecome user {name} login...".format(name=username)) 13 else: 14 print("invalid username or password!")
然后调用即可
1 import login #默认从当前目录到环境变量目录下找,所以放到环境变量目录下就行,或者将文件目录添加到环境变量目录下
5、内置常用模块
1.时间模块(time和datetime)
https://www.cnblogs.com/dangjf/p/15323664.html
2.随机模块(random)
random.random() #用于生成一个0到1的随机浮点数: 0 <= n < 1.0 random.uniform(1,10) #生成1-10区间的随机浮点数 random.randint(1,7) #生成随机整数n: a <= n <= b random.randrange(1,10) #从指定基数递增的集合中获取一个随机数n: a <= n < b random.choice(sequence) #从序列中获取一个随机元素,参数sequence表示一个有序类型,list, tuple, 字符串都属于sequence random.sample(sequence,3) #从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列 random.shuffle(items) #打乱指定序列
3.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 # 输出用于分割文件路径的字符串 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所指向的文件或者目录的最后修改时间
4.sys模块
sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit(n) #退出程序,正常退出时exit(0) sys.version #获取Python解释程序的版本信息 sys.maxint #最大的Int值 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform #返回操作系统平台名称 sys.stdout.write('please:') val = sys.stdin.readline()[:-1]
5.re模块
常用正则表达式符号
1 '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
2 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
3 '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
4 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a']
5 '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
6 '?' 匹配前一个字符1次或0次
7 '{m}' 匹配前一个字符m次
8 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
9 '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
10 '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
11
12
13 '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
14 '\Z' 匹配字符结尾,同$
15 '\d' 匹配数字0-9
16 '\D' 匹配非数字
17 '\w' 匹配[A-Za-z0-9]
18 '\W' 匹配非[A-Za-z0-9]
19 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
最常用的匹配语法
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
S(DOTALL): 点任意匹配模式,改变'.'的行为
5.shutil模块
shutil.copyfileobj(f1, f2) #将文件内容拷贝到另一个文件中,可以部分内容
shutil.copyfile(f1,f2) #拷贝文件
shutil.copymode(f1, f2) #仅拷贝权限。内容、组、用户均不变
shutil.copystat(f1, f2) #拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copy(src, dst) #拷贝文件和权限
shutil.copy2(src, dst) #拷贝文件和状态信息
shutil.copytree(src, dst, symlinks=False, ignore=None) #递归的去拷贝文件
shutil.rmtree(path[, ignore_errors[, onerror]]) #递归的去删除文件
shutil.move(src, dst) #递归的去移动文件
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
- 如:www =>保存至当前路径
- 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
- format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的
1 import zipfile 2 3 # 压缩 4 z = zipfile.ZipFile('laxi.zip', 'w') 5 z.write('a.log') 6 z.write('data.data') 7 z.close() 8 9 # 解压 10 z = zipfile.ZipFile('laxi.zip', 'r') 11 z.extractall() 12 z.close()
1 import tarfile 2 3 # 压缩 4 tar = tarfile.open('your.tar','w') 5 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip') 6 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip') 7 tar.close() 8 9 # 解压 10 tar = tarfile.open('your.tar','r') 11 tar.extractall() # 可设置解压地址 12 tar.close()
6.json和pickle模块
用于序列化的两个模块,可以将python数据类型转换为字符串或者字符串转为python数据类型,适用于多种语言数据交换。
json可以将简单python数据类型转换为字符串或者字符串转为python数据类型,适用于多种语言交换。
puckle只适用于python所有数据类型的转换
-
json,用于字符串 和 python数据类型间进行转换
-
pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
7. shelve模块
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
1 import shelve,datetime 2 3 d = shelve.open('shelve_test') #打开一个文件 4 # 写 5 info = {"age":22,"job":"it"} 6 name = ["alex","rain","test"] 7 8 d["name"] = name #持久化列表 9 d["info"] = info #持久化类 10 d["date"] = datetime.datetime.now() 11 # 读 12 print(d.get("name")) 13 print(d.get("info")) 14 print(d.get("date")) 15 d.close()
8.xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
1 <?xml version='1.0' encoding='utf-8'?> 2 <namelist> 3 <personinfo1 enrolled="yes"> 4 <name>abc</name> 5 <age checked="no">33</age> 6 <sex /> 7 </personinfo1> 8 <personinfo2 enrolled="no"> 9 <name>djf</name> 10 <age>19</age> 11 </personinfo2> 12 </namelist>
在python中可以用以下模块操作xml
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xml1.xml") 4 root = tree.getroot() 5 print(root) 6 print(root.tag) 7 print("---------") 8 # 遍历xml文档 9 for child in root: 10 print(child.tag, child.attrib) 11 for i in child: 12 print(i.tag, i.text) 13 print("---------") 14 # 只遍历year 节点 15 for node in root.iter('year'): 16 print(node.tag, node.text)
修改和删除xml文档内容
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xml1.xml") 4 root = tree.getroot() 5 6 # 修改 7 for node in root.iter('year'): 8 new_year = int(node.text) + 1 9 node.text = str(new_year) 10 node.set("updated", "yes") 11 12 tree.write("xml1.xml") 13 14 # 删除node 15 for country in root.findall('country'): 16 rank = int(country.find('rank').text) 17 if rank > 50: 18 root.remove(country) 19 20 tree.write('output.xml')
自己创建xml文档
1 import xml.etree.ElementTree as ET 2 3 new_xml = ET.Element("namelist") 4 personinfo1 = ET.SubElement(new_xml, "personinfo1", attrib={"enrolled": "yes"}) 5 name1 = ET.SubElement(personinfo1, "name") 6 age1 = ET.SubElement(personinfo1, "age", attrib={"checked": "no"}) 7 sex1 = ET.SubElement(personinfo1, "sex") 8 name1.text = "abc" 9 age1.text = '33' 10 personinfo2 = ET.SubElement(new_xml, "personinfo2", attrib={"enrolled": "no"}) 11 name2 = ET.SubElement(personinfo2, "name") 12 age2 = ET.SubElement(personinfo2, "age") 13 name2.text = "djf" 14 age2.text = '19' 15 16 et = ET.ElementTree(new_xml) # 生成文档对象 17 et.write("test.xml", encoding="utf-8", xml_declaration=True) 18 19 ET.dump(new_xml) # 打印生成的格式
9.PyYMAL模块
Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation
10.configparser模块
用于生成和修改常见配置文档
常见文档格式如下
1 [DEFAULT] 2 serveraliveinterval = 45 3 compression = yes 4 compressionlevel = 9 5 forwardx11 = yes 6 7 [bitbucket.org] 8 user = hg 9 10 [topsecret.server.com] 11 host port = 50022 12 forwardx11 = no
python生成文档
# 生成configparser文件 import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'} config['bitbucket.org'] = {} config['bitbucket.org']['User'] = 'hg' config['topsecret.server.com'] = {} topsecret = config['topsecret.server.com'] topsecret['Host Port'] = '50022' # mutates the parser topsecret['ForwardX11'] = 'no' # same here config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as configfile: config.write(configfile)
读改
1 import configparser 2 config = configparser.ConfigParser() 3 # 读 4 config.read('example.ini') 5 print(config.defaults(),config.sections()) 6 print(config["bitbucket.org"]) 7 for key in config['bitbucket.org']: 8 print(key) 9 10 # 改 11 config.remove_section("bitbucket.org") 12 config.write(open('example1.ini','w'))
11.hashlib模块
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
1 import hashlib 2 3 m = hashlib.md5() 4 m.update(b"Hello") 5 print(m.hexdigest()) 6 m.update(b"It's me") 7 print(m.hexdigest())# 16进制格式hash 8 print(m.digest()) #2进制格式hash 9 10 m1 = hashlib.md5() 11 m1.update(b"HelloIt's me") 12 print(m1.hexdigest())
python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密。
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的
真伪
1 import hmac 2 h = hmac.new(b'hello', b'it') 3 print(h.hexdigest())
12.logging模块
很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格
式的日志,logging的日志可以分为 debug()
, info()
, warning()
, error()
and critical() 5个级别,
下面我们看一下怎么用。
最简单用法
import logging logging.warning("user [alex] attempted wrong password more than 3 times") logging.critical("server is down") #输出 WARNING:root:user [alex] attempted wrong password more than 3 times CRITICAL:root:server is down
Level | When it’s used |
---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
如果想把日志写到文件里,也很简单
1 import logging 2 3 logging.basicConfig(filename='example.log',level=logging.INFO) 4 logging.debug('This message should go to the log file') 5 logging.info('So should this') 6 logging.warning('And this, too')
其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会
被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。
1 logging.basicConfig(filename='example.log',level=logging.INFO)
上面的日志格式加上时间
1 import logging 2 logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') 3 logging.warning('is when this event was logged.') 4 5 #输出 6 12/12/2010 11:46:36 AM is when this event was logged.
日志格式
%(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 |
字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d |
线程ID。可能没有 |
%(threadName)s |
线程名。可能没有 |
%(process)d |
进程ID。可能没有 |
%(message)s |
用户输出的消息 |