模块,说白了就是.py文件.那么使用模块有什么好处呢?好处就是大大的提高了代码的可维护性,同时编写代码代码有时候也没必要从零开始,我们可以直接用别人的.那么我们可以将模块分为三种: ①Python标准库,比如我们之前用到的time模块 ②第三方模块 ③应用程序自定义模块.那么我们怎么导入模块呢?方法如下:
①直接通过import来导入:比如导入的标准库里的模块和当前执行文件下的py文件
②通过from...import来导入:需要导入的py文件既不是标准库的也不是当前执行文件目录下的,我们就需要通过这种方法来导入
接下来,我们将学习标准库里面的一些常用模块
模块一:time
import time # time 返回当前的时间的时间戳 print(time.time()) # 输出结果是:1487085421.7728364 # 将时间戳转换为本地时间(也就是结构化时间) 如果传参数默认当前的时间戳 print(time.localtime()) # 输出结果是:time.struct_time(tm_year=2017, tm_mon=2, tm_mday=14, tm_hour=23, tm_min=19, tm_sec=32, tm_wday=1, tm_yday=45, tm_isdst=0) print(time.localtime(1387085519)) # 输出结果是:time.struct_time(tm_year=2013, tm_mon=12, tm_mday=15, tm_hour=13, tm_min=31, tm_sec=59, tm_wday=6, tm_yday=349, tm_isdst=0) # 将结构化时间转换成字符串时间 print(time.strftime("%Y-%m-%d %X",time.localtime())) # 输出结果是:2017-02-14 23:26:08 # 将字符串时间转换成结构化时间 print(time.strptime("2017-02-14 23:26:08","%Y-%m-%d %X")) # 输出结果是:time.struct_time(tm_year=2017, tm_mon=2, tm_mday=14, tm_hour=23, tm_min=26, tm_sec=8, tm_wday=1, tm_yday=45, tm_isdst=-1) # 将结构化时间转换成时间戳 print(time.mktime(time.localtime())) # 输出结果是:1487086079.0 # 将结构化时间转换成英文的时间表达式 不传参数默认使用当前的结构化时间 print(time.asctime()) # 输出结果是:Tue Feb 14 23:29:41 2017 # 将时间戳转换成英文的时间表达式 不传参数默认使用当前的时间戳 print(time.ctime()) # 输出结果是:Tue Feb 14 23:32:08 2017 # 推迟运行时间 time.sleep(1) # 延迟1秒
模块二:random
import random # 随机生成0-1的浮点数 print(random.random()) # 输出结果是:0.8100556093834125 # 取的范围是[x,y] print(random.randint(1,2)) # 输出结果是:1或者2 # 取的范围是[x,y) print(random.randrange(1,2)) # 输出结果是:1 # 随机取序列中的一个 print(random.choice("Jasonhy")) # 输出结果是:Jasonhy里面的任一个字母 # 指定序列中随机出现的个数 print(random.sample("Jasonhy",2)) # 输出的结果如:['h', 'a'] # 获取某个范围的浮点型 print(random.uniform(1,3)) # 输出结果如:2.56354190221493 # 打乱次序 var_l = [1,2,3,4,5] random.shuffle(var_l) print(var_l) # 输出结果如: [5, 2, 4, 3, 1] # 需求 生成验证码 含有数字和字母 def make_code(): code = "" for i in range(5): num = random.randint(0,9) letter = chr(random.randint(65,90)) # 随机从数字和字母组成的列表中选一个 cho = random.choice([num,letter]) code += str(cho) return code m_c = make_code() print(m_c)
模块三:os
import os # 主要是用来与操作系统进行交互的 # 获取当前的工作目录 print(os.getcwd()) # 输出结果是:D:\pyworkplace\test\blog # 改变当前脚本的工作目录 os.chdir("D:/pyworkplace/test") print(os.getcwd()) # 输出结果是:D:\pyworkplace\test # 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("bash command") 运行shell命令,直接显示 # os.environ 获取系统环境变量 path = os.path.abspath("模块.py") #返回path规范化的绝对路径 print(path) # 输出结果是: D:\pyworkplace\test\blog\模块.py path = os.path.split("模块.py") #将path分割成目录和文件名二元组返回 print(path) # 输出结果是: ('', '模块.py') # 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 path = os.path.join("模块.py","函数.py") #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 print(path) # 输出结果是:模块.py\函数.py # os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 # 返回path所指向的文件或者目录的最后修改时间 返回的是一个时间戳 print(os.path.getmtime("模块.py")) # 输出结果是:1487095673.0914783
模块四:sys
import sys # 命令行参数 第一个参数是程序本身路径 # 1,2,...则为命令行下传递的参数 print(sys.argv[0]) # 输出结果是:D:/pyworkplace/test/blog/模块.py # 获取操作系统的名称 比如我们有的程序需要在不同的平台下都能运行,这个时候我们就可以通过这个属性来进行不同的处理 print(sys.platform) # 输出结果是:win32 # 退出程序 sys.exit(n) 当n是0时表示正常退出,其他都不是正常退出,可抛出异常事件共捕获 # 搜索模块路径 print(sys.path) # 查找导入模块 print(sys.modules) # 标准输入 stdout 和标准错误 stderr 当我们的程序崩溃并打印调试信息的时候,信息前往stderr管道 # stdout是一个类文件对象,调用它的write函数可以打印给定的任何字符串,print真正做的事:在打印字符串的后面加上一个硬回车,然后用sys.stdout.write函数 # stderr也是类文件对象,但是它们都只有write方法,而没有read方法 saveout = sys.stdout # 在重定向之前保存stdout file = open("out.log","w") # 打开一个新的文件用于写入 sys.stdout = file # 将后续输出的都重定向到刚才打开的这个文件 print("日志信息...") sys.stdout = saveout # 设置为原来的方式 file.close()
os路径处理
#方式一:推荐使用
import os
#具体应用
import os,sys
possible_topdir = os.path.normpath(os.path.join(
os.path.abspath(__file__),
os.pardir, #上一级
os.pardir,
os.pardir
))
sys.path.insert(0,possible_topdir)
#方式二:不推荐使用
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
模块五:json
在介绍json模块之前,我们来回顾一下eval函数,eval可以将一个字符串转换成python对象,但是eval函数时有局限性的,对于普通的数据类型,eval是可以执行,并返回表达式的值.
import json x = "[null,true,false,1]" print(eval(x)) # 输出结果是:NameError: name 'null' is not defined print(json.loads(x)) # 输出结果是:[None, True, False, 1]
由于json表示出来的就是一个字符串,可以被所有的语言读取,也可以方便的存储到磁盘或者通过网络传输,他不仅是标准格式,而且比XML更快,XML我们将在后面讲到,而且可以在web页面中读取.json与python对应:
{} --->dict
[] --->list
"string" ---> str
123.22 ---> int或float
true/false ---> True/False
null ---> None
import json # json在进行写操作的是,如果是字符串,而且是单引号,就会将单引号变成双引号 # 如果没有引号,就会加上双引号 # dumps将数据变成字符串,然后写入文件 # dump可以直接将数据变成字符串,然后写入文件 with open("area","a",encoding="utf-8") as area: new_area = {"provice":"浙江省","p_capital":"杭州"} # dumps相关参数说明 ensure_ascii默认是True,也就是不管是不是ascii字符,都被转译成ascii字符,如果有中文或者其他非ascii字符,我们最好设置其为False,indent 缩进,默认为None,没有缩进,设置为正整数是,输出的字符将会按照indent指定的半角空格缩进,这个还是比较有用的,separators设置分隔符,默认的分隔符是(',',':'),如果需要自定义json中的分隔符,可以按照(item_separator,key_separator)的形式设置,sort_keys 默认为False,设置为True时,输出结果将会按照字典的key排序 print(json.dumps(new_area,ensure_ascii=False)) # 直接将转换好的字符串写入文件 第二参数是文件对象,其他参数都和dumps一样 json.dump(new_area,area,ensure_ascii=False) # loads获取文件中内容,将其变成对应的数据格式 # load的第一个参数就是文件对象 with open("area","r",encoding="utf-8") as area: # res = area.read() # print(json.loads(res)) print(json.load(area))
模块六:XML
xml是实现不同语言或程序之间数据交换的协议,跟json差不多,但是json使用起来更加简单,在这个模块中,我们主要学习的是ElementTree这个模块,是python的xml处理模块,它提供一个轻量级的对象模型,ElementTree表示整个xml节点树,Element表示节点树中的一个单独节点
创建xml文件:
# ET(tag) tag表示根节点,初始化一个ElementTree对象 # Element(tag,attrib={},**extra)用来构建一个xml的根节点,tag表示根节点名称,attrib是一个可选项,表示节点的属性 # SubElement(parent,tag,attrib={},**extra) 用来构建一个已经存在节点的子节点 # Element.text和SubElement.text表示element对象的额外属性 # Element.tag 和Element.attrib分别表示element对象的标签和属性 # ElementTree.write(file,encoding="",xml_declaration=None, default_namespace=None, method='xml')新建一个xml文件,并将节点数数据写入xml文件中 def make_location_population(): # 设置一个新的节点,并设置其标签为provice provice = ET.Element("provice",attrib={"p":"广东省"}) # 在provice下创建两个子节点,设置其名称分别为:p_capital,population p_capital = ET.SubElement(provice,"p_capital",attrib={"city":"广州市"}) # p_capital下创建一个子节点p_population p_population = ET.SubElement(p_capital,"p_population") p_population.text = "1亿人口" population = ET.SubElement(provice,"population",attrib={"all":"总人口"}) all_population = ET.SubElement(population,"all_population") all_population.text = "3亿人口" # 将节点数信息保存ElementTree中,并且保存为xml文件 tree = ET.ElementTree(provice) tree.write("loc_population.xml",encoding="utf-8",xml_declaration=True) make_location_population()
生成xml文件内容:
<provice p="广东省"> <p_capital city="广州市"> <p_population>1亿人口</p_population> </p_capital> <population all="总人口"> <all_population>3亿人口</all_population> </population> </provice>
解析和修改xml文件:
# 解析和修改xml文件 # ElementTree.parse(source,parser=None)将xml文件加载并返回ElementTree对象,parser是一个可选参数,如果为空,则默认使用标准的XMLParser解析器 # ElementTree.getroot():得到根节点,返回根节点的element对象 # Element.remove(tag):删除root下的名称为tag的子节点 # find(match):得到第一个匹配match的子节点,match可以是一个标签名或者是路径,它会返回一个list,包含匹配的elements信息 # iter(tag):创建一个以当前节点为根节点的elements信息 tree = ET.parse("loc_population.xml") p_capital = tree.find("p_capital") # 查找p_capital print(p_capital.attrib) # 输出结果是:{'city': '广州市'} for item in tree.iter("p_population"): item.text = "1.2亿" tree.write("loc_population.xml",encoding="utf-8")
修改之后的xml文件:
<provice p="广东省"> <p_capital city="广州市"> <p_population>1.2亿</p_population> </p_capital> <population all="总人口"> <all_population>3亿人口</all_population> </population> </provice>
模块七:re
就其本质而言,正则表达式是一种小型的,高度专业化的变成语言,它内嵌在python中,并通过re实现.正则表达式使用反斜杠字符("\")来表示特殊的形式或者允许使用特殊的字符而不要启用它们的特殊含义,比如我们要匹配一个反斜杠的字面值,我们需要写成"\\\\"作为模式字符串,因为正则表达式必须是"\\",每个反斜杠在python字符串字面值内必须表达成\\.我们可以通过python的原始字符串符号来表示正则表达式,我们只要以r为前缀的字符串字面值中,反斜杠不会以任何特殊的方式处理.比如r"\n"表示的一个"\"和一个"n"两个字符,而不是换行.我们需要注意的是大部分正则表达式操作可以利用模块级别的函数和RegexObject的方法,这些函数的快捷方式,它们不需要你首先编译一个正则表达式,但会遗漏一些调优的参数.
正则表达式指定一组匹配它的字符串,主要使用来检查给定的字符串是否匹配的给定的正则表达式.正则表达式可以连接以形成新的正则表达式,如果A和B两个都是正则表达式,那么AB也是正则表达式,一般来说,如果字符串p匹配A,且另一个字符串q匹配B,那么字符串pq将匹配AB.除非A或B包含低优级的操作或者A和B之间存在边界调节或者有编号的组的引用.
字符匹配:
# 元字符 . ^ $ * + ? {} # . 默认匹配除换行符以外的任意字符 res = re.findall("J..onhy","ABBDSDJasonhyDJDJSN") print(res) # 输出结果是: ['Jasonhy'] # ^ 默认模式下匹配字符串的起始位置 res = re.findall("^J..onhy","ABBDSDJasonhyDJDJSN") print(res) # 输出结果是:[] res = re.findall("^J..onhy","JasonhyDJDJSN") print(res) # 输出结果是: ['Jasonhy'] # $ 匹配字符串的末尾或者字符串末尾换行符之前的位置 res = re.findall("J..onhy$","ABBDSDJasonhyDJDJSN") print(res) # 输出结果是:[] res = re.findall("J..onhy$","ABBDSDJasonhy") print(res) # 输出结果是:['Jasonhy'] # * 匹配前面重复出现的正则表达式零次或多次,尽可能多匹配 res = re.findall("J.*onhy","ABBDSDJasonhyDJDJSN") print(res) # 输出结果是:['Jasonhy'] res = re.findall("J.*onhy","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Jaaaaasonhy'] res = re.findall("Ja*","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Jaaaaa', 'J', 'J'] # + 匹配前面的一个或多个 res = re.findall("Ja+","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Jaaaaa'] # ? 匹配前面的0个或1个 res = re.findall("Ja?","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Ja', 'J', 'J'] # {} 定自己匹配的范围 按照最多来匹配 res = re.findall("Ja{1,3}","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Jaaa'] # {}? 按照最少来匹配 res = re.findall("Ja{1,3}?","ABBDSDJaaaaasonhyDJDJSN") print(res) # 输出结果是:['Ja'] # \ 对任一特殊字符进行转义 比如我们要匹配* res = re.findall("\*","A****") print(res) # 输出结果是:['*', '*', '*', '*'] # 字符集[] 来用表示一个字符集合,在集合中: # 1,字符可以一个个列出来,如[abc]将匹配"a","b"或"c" # 2,通过给出两个字符,并用-分割,如[a-z]将匹配小写a-z的任一字符,[0,1][0,9]将匹配00-19之间的两位数,[0-9A-Fa-f]将匹配任意一个十六进制数字,如果-被转义(例如[a\-z]或者它位于第一个或最后一个字符(例如[a-],它将只匹配第一个字面值- # 3,在集合的内部特殊字符将失去它们的特殊含义,例如[(+*)]将匹配字面值"(","+","*",")" # 4,在集合中还接受字符类别,例如\w或\S(下面将会介绍) # 5,不在一段范围之内的字符可以通过补集匹配,如果集合的第一个字符是^,那么所有不在集合的字符都将被匹配,例如[^5],匹配除了5之外的所有字符,[^^]将匹配除了^之外的所有字符,如果^不是集合中的第一个字符,则没有特殊的含义 # 6,若要匹配集合中的一个字符字面值"]",可以在在它的前面放一个反斜杠或者放在集合的开始 res = re.findall("[1-9]","45454da-da4798rdas") print(res) # 输出结果是:['4', '5', '4', '5', '4', '4', '7', '9', '8'] res = re.findall("[1\-9]","45454da-da4798rdas") print(res) # 输出结果是:['-', '9'] res = re.findall("[(*)]","fhjsd(jd)JK12*4") print(res) # 输出结果是:['(', ')', '*'] res = re.findall("[^^]","fhjds^ji45") print(res) # 输出结果是:['f', 'h', 'j', 'd', 's', 'j', 'i', '4', '5'] # | 管道符 或的意思 只要匹配到一个就不再匹配 res = re.findall("kw|a","hjkwajjjkwhjdsdwa") print(res) # 输出结果是:['kw', 'a', 'kw', 'a'] # () 分组 匹配任何在圆括号内的正则表达式,并表明分组的开始和结束 + 表示匹配得到的提取出一个 没有+表示只要匹配到了,就提取出来 res = re.findall("(abc)+","abcabcab") print(res) # 输出结果是:['abc'] res = re.findall("(abc)","abcabcab") print(res) # 输出结果是:['abc', 'abc'] # \d --> 0-9的任何一个数字 \D --> 非数字部分 \s -->空白字符,比如\t \S --> 非空白字符 \w --> 字母,数字字符 \W -->非字母,数字字符 \b -->特殊字符边界比如空格,&,#等
注:如果我们使用管道符的,比如我现在要匹配一个邮箱,Jasonhy1970@gmail.com 现在我匹配的规则是 gmail|163 匹配到之后我要全部输出,这个时候我们应该这么做:
res = re.findall("Jasonhy1970@(?:gmail|163).com","Jasonhy1970@gmail.com") print(res) # 输出结果是:['Jasonhy1970@gmail.com']
常用函数:
# compile(patter,flags=0):将正则表达式模式编译成一个正则表达式对象,可以用于匹配使用它的match()和search()方法,flags值修改表达式的行为,当编译成一个对象之后,这种规则就可以多次使用了,提高了重用性 rc = re.compile("\d+") print(re.findall(rc,"hjf4ff78rd545ad")) # 输出结果是:['4', '78', '545'] # search(pattern,string,flags=0):扫描字符串,寻找的第一个由该正则表达式模式产生的匹配的位置,并返回响应的MatchObject实例,只要找到一个就不再找了 通过group()取出 res = re.search("b","abcd45b") print(res.group()) # 输出结果是:b # match(pattern,string,flags=0):如果字符串的开头的零个或更多字符匹配正则表达式模式,返回MatchObject实例,返回None则该字符串中与模式不匹配,只匹配字符串的开头,相当于search的前面加了一个^,通过group取出 res = re.match("\d+","12asjdksa12fds45ad") print(res.group()) # 输出结果是:12 # split(pattern,string,maxsplit=0,flags=0):将字符串拆分的模式匹配,如果在模式中使用捕获括号,则然后也结果列表的一部分返回文本模式中的所有组,如果maxsplit不为0,顶多maxsplit分裂,并且该列表的其余部分作为最后一个元素返回 res = re.split("a","dhjasajjasjjas") print(res) # 返回结果是:['dhj', 's', 'jj', 'sjj', 's'] res = re.split("a","dhjasajjasjjas",3) print(res) # 返回结果是:['dhj', 's', 'jj', 'sjjas'] res = re.split("a","abaca") # 如果左边没有内容的话就是空串,右边没有的话也同样是一个空串 print(res) # 输出结果是:['', 'b', 'c', ''] # finditer(pattern,string,flags=0):将结果封装到一个迭代器中,如果数据过多的时候,这样做可以节省内存 一个MatchObject对象的迭代器 遍历之后通过group取出 res = re.finditer("\d+","12adad45fd8rew456sf123456sf") for item in res: print(item.group()) # sub(pattern,repl,string,count=0,flags=0):repl表示替换匹配到的元素,count表示替换的次数 res = re.sub("A","a","AbcAbc",count=1) print(res) # 输出结果是:abcAbc # subn:返回的结果是一个元组 返回结果的第二个参数表示匹配到的次数 res = re.subn("A","a","AbcAbcAbc",count=2) print(res) # 输出结果是:('abcabcAbc', 2)
模块八:logging
这个模块主要用来做日志输出的,默认情况下logging将日志打印到标准输出当中,且中显示大于等于WARNING的日志,日志级别是:CRITICAL >ERROR >WARNING>INFO >DEBUG >NOTSET
import logging # 设置日志级别 # filemode默认是a # format指定handler使用的日志格式 # datefmt指定日期格式 # level指定日志级别 # format参数中可能用到的格式化串: # stream用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 # %(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用户输出的消息 logging.basicConfig(level=logging.DEBUG, # 日志为最低级别 format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s", # 显示的格式 []里面是行号 datefmt="%a,%d %b %Y %H:%M:%S", filename="test.log", filemode="w") # 覆盖的形式 logging.debug("这是debug") logging.info("这是info") logging.warning("这是warning") logging.error("这是error") logging.critical("这是critical") # 创建日志对象 logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler("test.log") # 创建一个handler,用于输出到控制台 ch = logging.StreamHandler() # 设置显示格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 将显示格式分别设置到handler中 fh.setFormatter(formatter) ch.setFormatter(formatter) # 将handler添加到 logger.addHandler(fh) logger.addHandler(ch) # 设置级别 logger.level = logging.DEBUG logger.debug("对象的debug") logger.info("对象的info") logger.warning("对象的warning") logger.error("对象的error") logger.critical("对象的critical")
日志文件的信息:
Fri,17 Feb 2017 00:04:17 模块.py[line:10] DEBUG 这是debug Fri,17 Feb 2017 00:04:17 模块.py[line:11] INFO 这是info Fri,17 Feb 2017 00:04:17 模块.py[line:12] WARNING 这是warning Fri,17 Feb 2017 00:04:17 模块.py[line:13] ERROR 这是error Fri,17 Feb 2017 00:04:17 模块.py[line:14] CRITICAL 这是critical 2017-02-17 00:21:29,053 - root - WARNING - 对象的warning 2017-02-17 00:21:29,054 - root - ERROR - 对象的error 2017-02-17 00:21:29,054 - root - CRITICAL - 对象的critical 2017-02-17 00:22:34,831 - root - DEBUG - 对象的debug 2017-02-17 00:22:34,832 - root - INFO - 对象的info 2017-02-17 00:22:34,832 - root - WARNING - 对象的warning 2017-02-17 00:22:34,833 - root - ERROR - 对象的error 2017-02-17 00:22:34,833 - root - CRITICAL - 对象的critical
封装log工具类
import logging class Logger: def __init__(self, logger, filename, level=logging.DEBUG, datefmt="%a,%d %b %Y %H:%M:%S", filemode="a"): logging.basicConfig( level=level, format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s", datefmt=datefmt, filename=filename, filemode=filemode ) self.log = logging.getLogger(logger) def get_log(self): return self.log
注:当我们创建子对象的时候,对象名不能一样,也是说这里的logging.getLogger(name)name不能一样,如果一样了,无论你创建了多少个子对象,都是同一个对象
接下来还有一些模块,比如configparse模块,hashlib模块等,自己不怎么用,用到的时候再说吧
ElementTree - 转载请保留原文链接:https://www.noniu.com/jiaocheng/211.html
浙公网安备 33010602011771号