模块定义及导入
模块,用一砣代码实现了某个功能的代码集合。
类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。
如:os 是系统相关的模块;file是文件操作相关的模块
模块分为三种:
- 自定义模块
- 内置标准模块(又称标准库)
- 开源模块
自定义模块 和开源模块的使用参考 http://www.cnblogs.com/wupeiqi/articles/4963027.html
参考alex模块博客https://www.cnblogs.com/alex3714/articles/5161349.html
1 from test123 import * 2 ''' 3 不是间接调用文件,而是直接等同于复制代码,所以在此处调用内部功能时 4 无需加模块名,直接将使用功能即可例如: 5 ''' 6 7 from test123 import test as a #如果怕重名导致覆盖可以改名 8 9 import package #导入一个包就是在执行__init__文件 10 ''' 11 若要导入包下的其他文件,则需把其他文件写入init中,通过init来运行 12 '''
OS模块
提供对操作系统进行调用的接口
1 os.path.abspath(__file__) #某个文件的绝对路径 2 3 os.path.dirname(绝对路径) #返回父级目录 4 5 os.getcwd() #获取当前操作目录 6 7 os.chdir(".") #切换目录 8 9 os.pardir #获得当前目录的父级目录 #'..'代表父级目录 10 11 os.curdir #返回当前目录 #'.'代表当前目录 12 13 os.makedirs(r"D:\a\b\c\d") 14 ''' 15 创建目录,若缺少上级 16 则递归的创建目录:创建多级目录 17 ''' 18 19 os.removedirs(r'd:\\a\\b\\c\\d') 20 ''' 21 删除空文件夹,若文件夹不为空,停止删除 22 若为空,继续往上层删 23 ''' 24 25 #os.mkdir(r'D:\a1\b') #创建目录,不能递归创建,缺少父级就不能创建 26 27 #os.rmdir(r'd:\a1\b\c') #删除空文件夹,不能递归删除,只删除指定的 28 29 os.listdir('.') #列出指定目录 30 31 os.remove() #删除一个文件 32 33 os.rename("oldname+路径","newname+路径") #更改文件名 34 35 os.stat(r"os模块1.py") #查看文件属性
1 os.sep #输出当前操作系统的路径分隔符 2 3 os.linesep #输出当前操作系统的换行分隔符 4 5 os.pathsep #输出用于分割文件路径的字符串 6 7 os.environ #找出当前环境所有的环境变量 8 9 os.name #输出当前使用平台 10 11 os.system() 12 ''' 13 运行shell命令,直接显示 14 dir:显示当前目录 15 ipconfig/all:显示IP 16 ''' 17 18 os.path.abspath() 19 ''' 20 获取某个文件绝对路径 21 配合sys.path.append()将其加入环境变量 22 ''' 23 24 os.path.split(r"D:\\a\\b\\c\\d.txt") 25 ''' 26 分割路径,变成一个元组形式 27 将d.txt与前面的路径分割成两个字符串 28 ''' 29 30 os.path.dirname(r"D:\\a\\b\\c\\d.txt") #获取目录名 31 32 os.path.basename(r"D:\\a\\b\\c\\d.txt") #获取文件名 33 34 os.path.exists(r"D:\\OXMLG") #判断路径是否存在 35 36 os.path.isabs(r'OXMLG.txt') #判断是否为绝对路径 37 38 os.path.isfile(__file__) #判断是否是一个文件(非目录) 39 40 os.path.isdir(r"D:\\a\\b\\c\\d.txt") #是否是目录 41 42 os.path.join(r"C:\\",r'a\\',r'b\\',r'c') #将路径组合 43 44 os.path.getatime(r'D:\\ARCGIS') #返回path所指向的文件或者目录的最后存取时间 45 46 os.path.getmtime(r'D:\\ARCGIS') #返回path所指向的文件或者目录的最后修改时间
sys模块
1
2
3
4
5
6
7
8
|
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 ]
|
1 sys.path 2 ''' 3 打印所有能引用模块的目录 4 若想添加新的目录,则需在此列表添加即可 5 ''' 6 7 sys.path.append(a) #将某个绝对路径加入环境变量 8 9 sys.argv #引用参数
random随机数模块
1 random.random() #随机取一个浮点数,范围0-1 2 3 random.uniform(1,10) #随机取浮点数,可指定区间 4 5 random.randint(1,10) #随机取整,前后都是闭 6 7 random.randrange(1,10) #随机取整,前闭后开 8 9 random.choice("helllo") 10 ''' 11 从序列中随机取值 12 序列可是列表、字符串、元组 13 ''' 14 15 random.sample(["xingtao","suiqiaoli","age:21","sex:boy","i lvove you"],2) 16 ''' 17 从序列中随机取值 18 可定义取值数量 19 ''' 20 21 22 random.shuffle([1,2,3,4,5,6,7]) #随即打乱顺序
1 import random 2 x = '' 3 for i in range(4): 4 a = random.randint(0,3) 5 if i == a: #制造数字与字母的随机性 6 q=chr(random.randint(65,90)) #65-90对应A-Z 7 x += str(q) 8 else: 9 w=random.randint(0,9) 10 x+=str(w) 11 print(x) 12 while True: 13 key = input("write please:") 14 if key == x: 15 print("welcome") 16 break 17 else: 18 print('wrong')
time时间模块
1 time.time() #时间戳,表示目前的时间-1970年的时间,以秒计时 2 3 4 x=time.localtime() #元组时间 5 ''' 6 本地时间 7 year: 4位整数 8 mouth: 1-12 9 day: 1-31 10 hours: 0-23 11 minutes: 0-59 12 seconds: 0-59 13 weekday: 0-6 ,Monday is 0 14 ''' 15 x.tm_year #只取年,取出别的也可用类似方法 16 17 time.gmtime() 18 ''' 19 UTC世界标准时 20 格式同上 21 可写入时间戳,输出元组时间 22 ''' 23 24 time.timezone 25 ''' 26 世界标准时和本地时间的差值 27 单位为秒,换算后是8小时,对应UTC-8 28 ''' 29 30 time.altzone #和夏令时差值 31 32 time.daylight #是否使用夏令时 33 34 time.sleep(1) #睡眠X秒 35 36 time.mktime(x) 37 ''' 38 通过传入元组时间 39 得到时间对应的时间戳 40 ''' 41 42 time.strftime("%Y-%m-%d %H:%M:%S weekday:%a %A ") 43 time.strftime("%r , %x ,%g ,%h ,%p ,%c" ) 44 ''' 45 元组转格式化(注意区分大小写) 46 %Y 年 47 %m 月 48 %d 日 49 %H 时 50 %M 分 51 %S 秒 52 %Z UTC-time 53 %a 星期(缩写) 54 %A 星期(全拼) 55 除此外还有很多未知的格式化 56 如上式中的%r %x等 57 ''' 58 time.strptime("2018-08-07 20:49:42","%Y-%m-%d %H:%M:%S") 59 ''' 60 格式化转元组 61 输入时间,并输入对应格式化即可 62 ''' 63 64 time.asctime() #把元组转换成字符串 65 66 time.ctime() #把时间戳转换成字符串
1 datetime.datetime.now() #获取当前时间 2 3 datetime.datetime.now()+datetime.timedelta(+3) #3天后的时间 4 5 datetime.datetime.now()+datetime.timedelta(-3) #3天前的时间 6 7 datetime.datetime.now()+datetime.timedelta(hours=+10,minutes=-20,seconds=-44.476) #修改时间 8 ''' 9 datetime.timedelta()不能单独使用,必须配合datetime.datetime.now()使用 10 '''
1 a=datetime.datetime.now() 2 a.replace(year=1,month=2,day=3,hour=4,minute=5,second=6) #直接更改当前时间
shelve模块
shelve模块是一个简单的key,value将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
1 import shelve,datetime 2 with shelve.open('shelve_test') as d: 3 '''持久化,就是创建一个新的文件把要持久化的数据存里''' 4 info = {'age':21,'job':"it"} 5 name=['xingtao','suiqiaoli'] 6 7 d['name']=name 8 d['info']=info 9 d['date']=datetime.datetime.now() 10 11 with shelve.open('shelve_test') as d: 12 '''读取持久化文件''' 13 print(d.get('name')) 14 print(d.get('info')) 15 print(d.get('date'))
序列化模块
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
1 import json #一般只能对简单的对象使用,主要用于不同语言间的交互,比如把一个字典从python传到java 2 3 with open("test.txt","w",encoding="utf-8") as test_file: 4 a={'name': 'xingtao', 'age': 21} 5 d=json.dumps(a) #序列化 #dump 及 load最多用一次!!!第二次必须换对象或存储的文件 6 test_file.write(d) 7 8 with open("test.txt","r",encoding="utf-8") as test_file: 9 c=json.loads(test_file.read()) 10 print(c["age"]) #反序列化
1 def sayhi(name): 2 print("hello",name) 3 4 5 import pickle #能序列化一切数据类型 6 7 with open("test.txt","wb") as test_file: #pickle 有一套自己的语言,读写都要用二进制 8 a={'name': 'xingtao', 'age': 21,"func":sayhi} #只能在本语言中用,别的语言不认识 9 e=pickle.dumps(a) #语法和json完全相同 10 test_file.write(e) 11 12 with open("test.txt","rb") as test_file: 13 c=pickle.loads(test_file.read()) #注意,反序列化的func需要找到同名的数据对象 14 print(c) #若在另一个文件中反序列化,则找不到会出错 15 #若想强行用,就把原数据粘过去 16 print(c["func"]("xingtao"))
XML模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
1 <data> 2 <country name="Liechtenstein"> 3 <rank updated="yes">2</rank> 4 <year user_name="xingtao">2018</year> 5 <gdppc>141100</gdppc> 6 <neighbor direction="E" name="Austria" /> 7 <neighbor direction="W" name="Switzerland" /> 8 </country> 9 <country name="Singapore"> 10 <rank updated="yes">5</rank> 11 <year user_name="xingtao">2021</year> 12 <gdppc>59900</gdppc> 13 <neighbor direction="N" name="Malaysia" /> 14 </country> 15 <country name="Panama"> 16 <rank updated="yes">69</rank> 17 <year user_name="xingtao">2021</year> 18 <gdppc>13600</gdppc> 19 <neighbor direction="W" name="Costa Rica" /> 20 <neighbor direction="E" name="Colombia" /> 21 </country> 22 </data>
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xml_test.xml") 4 root = tree.getroot() 5 print(tree) 6 print(root) 7 print(root.tag) 8 9 # 遍历xml文档 10 for child in root: 11 print(child.tag,"---->>%s"%child.attrib) 12 for i in child: 13 '''tag是标签,text是值,attrib是属性''' 14 print(i.tag, "<%s>"%i.text,"<<%s>>"%i.attrib) 15 16 # 只遍历year 节点 17 for node in root.iter('year'): 18 '''iter是遍历所有,也可输入标签遍历查找''' 19 print("------》",node.tag, node.text) 20 21 #修改 22 for node in root.iter("year"): 23 '''修改是直接覆盖原属性和值''' 24 new_year=int(node.text)+1 25 node.text=str(new_year) #写入值 26 node.set("user_name","xingtao") #写入属性(键,值) 27 print("年份+1并写入属性",node.tag,node.text,"<%s>"%node.attrib) 28 29 tree.write("xml_test.xml") #写入文件 30 31 #删除 32 for node in root.findall("country"): 33 ''' 在country中找到rank,再根据rank的text值删除country ''' 34 rank=int(node.find('rank').text) 35 if rank >50: 36 root.remove(node) 37 38 tree.write("output.xml")
1 import xml.etree.cElementTree as ET 2 3 new_xml=ET.Element("name_list") #根节点 4 5 name1=ET.SubElement(new_xml,"name",attrib={"name":"xingtao","enrolled":"yes"}) 6 ''' 7 sub代表子节点(依附的节点,节点名,属性) 8 ''' 9 10 age1=ET.SubElement(name1,"age") 11 sex1=ET.SubElement(name1,"sex",attrib={"sex":"boy"}) 12 age1.text="21" #对子节点赋值 13 14 name2=ET.SubElement(new_xml,"name",attrib={"name":"suiqiaoli","enrolled":"yes"}) 15 16 age2=ET.SubElement(name2,"age") 17 sex2=ET.SubElement(name2,"sex",attrib={"sex":"girl"}) 18 age2.text="21" 19 20 et=ET.ElementTree(new_xml) #生成文档对象 21 et.write("new_xml.xml",encoding='utf-8',xml_declaration=True) #写入 22 23 ET.dump(new_xml) #序列化
PyYAML模块
Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation
ConfigParser模块
用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 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 port = 50022 12 forwardx11 = no
1 import configparser 2 3 config = configparser.ConfigParser() #生成一个调用对象,注意区分大小写 4 5 config['DEFAULT']={'ServerAliveInterval':45, 6 'Compression':'yes', 7 'CompressionLevel':9, 8 'ForwardX11':'yes' } 9 10 config['bitbucket.org']={'user':'hg'} 11 12 config['topsecret.server.com']={'port':50022, 13 'ForwardX11':'no'} 14 15 with open('example.conf','w',encoding='utf-8') as example: 16 config.write(example) #注意写入格式 17 18 ''' 19 读写和改直接去找源文件读改得了 20 不用在命令里费劲 21 '''
hashlib、hmac加密模块
hashlib模块用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
1 import hashlib 2 3 m=hashlib.md5() #MD5无法反解 4 m.update(b'hello') #b是byte字节,必须要有 5 m.hexdigest() #16进制加密 6 m.update(b'word') #第二次update是更新,是将之前的和这次放在一起 7 m.hexdigest() 8 9 m2=hashlib.md5() 10 m2.update(b'OXMLG') #不知道啥进制加密 11 m2.digest() 12 13 s1=hashlib.sha512() #sha加密 14 s1.update(b'hello') 15 s1.hexdigest() 16 s1.update('邢韬'.encode('utf-8')) #中文时要去掉字节符并转码 17 s1.hexdigest()
1 import hmac 2 3 h =hmac.new("天王盖地虎".encode('utf-8'),b'12345') 双层加密,把值用一个key代替,再把key进行加密 4 h.hexdigest()
re正则表达式
1 re.match("xin","xingtao12331") #match只能从第一个字符开始搜索 2 3 res=re.match('xing\d+','xing123woshitao123456') #\d+代表后面的所有数字 4 5 res.group() #打印取得的字符 6 7 res=re.match('.+t','xing123woshitao123456') #默认匹配除\n之外的任意一个字符 8 9 re.search("xing","taoxing666") #search可从任意字符开始搜索 10 11 re.search("t.+6$",'xing123woshitao123456') # $代表源字符串必须以某个字符结尾才可使用,否则返回为NONE 12 13 re.search("w[a-zA-Z]",'xing123woshitao123456') #只选字母 14 15 re.search("a?",'xing123woshitao123456') #匹配?前一个字符1次或0次 16 re.search('[0-9]{3}','adas23sa1ds124fdgdf') #匹配前一个字符m次 17 re.search('[0-9]{1,3}','adas23sa1ds124fdgdf') #匹配前一个字符n到m次 18 19 re.search('(123){2}\|\|{3}','''fafds123123|||safsfs''') #若加括号代表整体 #\代表转译符 20 21 re.findall('[0-9]{1,3}','adas23sa1ds124fdgdf') #findall能寻找所有,而不是第一个找到的 22 23 re.findall('abc|ABC','ABCBabcCD') #匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果ABC''' 24 25 re.findall('\D+','123asa%da') # \D除了数字以外的字符 26 27 re.findall('\w+','123asa%da') # \w除了特殊字符以外的 28 29 re.findall('\W+','123(as……a%da') # \W只匹配特殊字符 30 31 re.findall('\s+',' fasf \n \r ') # \s只匹配空格、换行等 32 33 a=re.search("(?P<nember>[04])(?P<id>[a-zA-Z]+)","01qeqe02asfas03saf04ssaf05fafsa06afaf") #变成字典 34 b=a.groupdict() 35 print(b) 36 37 re.search("(?P<sheng>[0-9]{2})(?P<shi>[0-9]{3,4})(?P<xian>[0-9]{5,6})(?P<birthday>[0-9]{7,14})","231024199611260019").groupdict() #利用groupdict拆解身份证 38 39 re.split('[0-9]+',"saf78sa7fsafs8fsa8fa89f") #按照某个或某种字符进行分割 40 41 re.sub("[0-9]+","|","saf78sa7fsafs8fsa8fa89f",count=3) #替换,count为替换数量(可有可无) 42 43 re.search("[a-z]+","afasfSADSAD",flags=re.I) #re.I 忽略大小写问题 44 45 re.search(".+","asfsaf\ngrggad\nwacrfd",flags=re.S) #re.S 让\n也可以匹配
logging日志模块
1 import logging 2 3 logging.basicConfig(filename="logging_example.log",level=logging.INFO, 4 format="%(asctime)s-->>%(message)s",datefmt="%Y-%m-%d %H:%M:%S") 5 ''' 6 filename:日志名 7 level:等级(低于该等级都不会输出) 8 format:输出格式(具体见列表) 9 datefmt:时间格式 10 ''' 11 logging.debug('debug') 12 logging.info("info") 13 logging.warning("not wrong") 14 logging.error("wrong") 15 logging.critical("wrong_wrong")
1 ''' 2 %(asctime)s 时间,默认输出格式为 X-X-X X:X:X.XXX 3 %(name)s logger对象的名字,可通过getLogger键入 4 %(filename)s 打印文件路径及文件名 5 %(levelname)s 等级 6 %(message)s 日志内容 7 %(funcName)s 函数名称 8 %(levelno)s 把level底层数字的形式打印出来 9 %(lineno)d 把具体某行打印出来 10 %(module)s 只打印文件名 11 %(pathname)s 路径名 12 %(process)d 哪个进程打印的 13 %(processName)s 进程名 14 %(thread)d 线程 15 %(threadName)s 线程名 16 '''
''' logger提供了应用程序可以直接使用的接口; handler将(logger创建的)日志记录发送到合适的目的输出; filter提供了细度设备来决定输出哪条日志记录; formatter决定日志记录的最终输出格式。 '''
1 import logging 2 ''' 3 首先设定logger 4 然后设定handler 5 然后设定formatter 6 然后把formatter注册给handler 7 然后把handler注册给logger 8 然后打印要输出的日志 9 ''' 10 11 logger=logging.getLogger("test") #获取logger对象 12 logger.setLevel(logging.DEBUG) #设置一个全局的日志等级 13 ''' 14 主要作用是负责接收日志 15 ''' 16 17 ch=logging.StreamHandler() #打印到屏幕 18 ch.setLevel(logging.INFO) #设置局部的日志等级(不能低于全局日志等级,否则无法生效) 19 20 fh=logging.FileHandler("logging_example.log") #打印到文件 21 fh.setLevel(logging.ERROR) 22 ''' 23 可以设置不同的输出方式打印不同的日志级别 24 ''' 25 26 formatter=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") 27 formatter_file=logging.Formatter("%(asctime)s - %(filename)s - %(levelname)s - %(message)s") #设置格式 28 ch.setFormatter(formatter) 29 fh.setFormatter(formatter_file) 30 ''' 31 可以为不同的输出方式添加不同的格式输出格式 32 ''' 33 34 logger.addHandler(fh) #把日志打印到指定的方式中 35 logger.addHandler(ch) 36 37 logger.debug('debug') 38 logger.info("info") 39 logger.warning("not wrong") 40 logger.error("wrong") 41 logger.critical("wrong_wrong")