python—模块与包

模块:

一个.py文件就是一个模块module,模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能。

  模块分三种: 1.python标准库 2.第三方模块 3.应用程序自定义模块 

   下面,先重点讲第三个,应用程序自定义模块

 1 在同一个python package包里面建立两个python file(如,cal.py  test.py)
 2 
 3 在cal.py文件里:
 4 print('ok')
 5 def add(x,y):
 6     return x+y
 7 def sub(x,y):
 8     return x-y
 9 print('ojbk')
10 
11 在test.py文件里:
12 import cal 
13 print(cal.add(3,5)) #非得加cal.
14 print(cal.sub(6,4)) #非得加cal.
#结果:ok ojbk 8 2
(这个执行,会先执行cal.py文件的,cal.py文件全部执行一遍才会执行test.py文件)
15 16 如果不想加cal.可以: 17 from cal import add 18 from cal import sub 19 print(add(3,5)) 20 print(sub(6,4)) 21 用from 这样就不需要加cal. 22 23 from cal import add 24 from cal import sub 25 可以将其用from cal import * 代替;*星号就代表所有 #但是不推荐使用 26 27 这个import导入的模块会做三件事: 28 #import模块做了三件事,1:执行对应文件 2.引入变量名cal 29 30 想导入多个模块可以在模块名后面加逗号隔开,如:import cal,time

    关于,import路径问题:

1 import sys
2 print(sys.path)
3 #['C:\Users\zy\PycharmProjects\python全站-s3\day20\module_lesson'......]
4 #这就是import最主要的路径
5 
6 当我们给module_lesson这一级再建一个package包,my_module,将cal.py文件放入,cal.py文件与test.py文件不在同一个包里面,而与my_module同级,可以:
7 from my_module import cal     

     关于,包 package(组织模块):

1 关于包的调用,与模块的调用一样,from import
2 (假如是三层,web,web1,web2,在web2里面调用它的cal.py文件)
3 方法一:from web.web1.web2 import cal
4           print(cal.add(2,6))
5 方法二:from web.web1.web2.cal import add
6           print(add(2,6))
7 #from web.web1 import web2(执行web3的__init__文件,唯一不支持的调用方式)

     关于,__name__

 1 在执行文件里写;
 2 print(__name__)
 3 #结果:__main__   
 4 
 5 在被调用文件里写;
 6 print(__name__)
 7 #结果:被调用文件的路径
 8 
 9 if __name__=="__main__":
10 有两个作用:
11 【1】在被调用文件里面,它后面文件不会被调用执行,用于被调用文件的测试
12 【2】在执行文件里面,不想执行文件被其它文件调用

   下面介绍,python标准库: 

【1】时间模块:

 1 import time
 2 time.sleep(2)
 3 print('ok')
 4 #结果:ok (会停顿两秒,再出现ok)
 5 
 6 时间戳
 7 import time
 8 print(time.time())
 9 #结果:1535856591.4900608(从1976年开始到现在为止经历了多少秒数)
10 
11 结构化时间
12 import time
13 print(time.localtime())
14 t=time.localtime()
15 print(t.tm_year)
16 print(t.tm_wday)
17 #结果:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=2, #tm_hour=10, tm_min=53, tm_sec=58, tm_wday=6, tm_yday=245, #tm_isdst=0)
18 #2018
19 #6
20 
21 字符串时间
22 
23 将结构化时间转换成时间戳
24 import time
25 print(time.mktime(time.localtime()))
26 #结果:1535857837.0
27 
28 将结构化时间转换成字符串时间
29 import time
30 print(time.strftime('%Y-%m-%d %X',time.localtime()))
31 #结果:2018-09-02 11:15:40
32 (%Y-%m-%d表示年月日; %X表示时分秒;逗号后面是结构化时间)
33 
34 将字符串时间转化成结构化时间
35 import time
36 print(time.strptime('2018:09:02:11:29:12','%Y:%m:%d:%X'))
37 #结果:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=2, #tm_hour=11, tm_min=29, tm_sec=12, tm_wday=6, tm_yday=245, #tm_isdst=-1)
38 
39 把一个表示时间的元组或者struct_time表示为以下这种形式
40 import time
41 print(time.asctime())
42 #结果:Sun Sep  2 11:32:59 2018
43 
44 另外一种时间表示形式
45 import datetime
46 print(datetime.datetime.now())
47 #结果:2018-09-02 11:41:09.032006

【2】random模块:

 1 import random
 2 ret=random.random()
 3 print(ret)  #0-1之间的随机数
 4 ret1=random.randint(1,3)
 5 print(ret1)
 6 ret2=random.randrange(1,3)   #左取右不取
 7 print(ret2)
 8 ret3=random.choice([11,22,33])
 9 print(ret3)
10 ret4=random.sample([11,22,33],2)  #在列表中任意取两个
11 print(ret4)
12 ret5=random.uniform(1,3)  #取1-3之间的浮点数
13 print(ret5)
14 item=[1,2,3,4,5,6]
15 random.shuffle(item)
16 print(item)
17 #结果:0.3145521479730945
18 #     1
19 #     2
20 #     22
21 #     [11, 22]
22 #     1.063056970721215
23 #     [5, 2, 3, 6, 1, 4]
24 
25 随机验证码:
26 import random
27 def v_code():
28     ret=''
29     for i in range(4):
30         num=random.randint(0,9)
31         alf=chr(random.randint(65,122))
32         s=str(random.choice([num,alf]))
33         ret+=s
34     return ret
35 print(v_code())
36 #结果:eP2R

【3】os模块:

1 import os
2 print(os.getcwd()) #获取当前目录
3 print(os.stat('修饰器.py'))  #与文件相关的信息
4 print(os.system('dir'))   #显示文件所有信息
5 a='C:UserszyPycharmProjects'
6 b='python全站-s3'
7 print(os.path.join(a,b))  #路径拼接

【4】sys模块:

1 #sys.argv  命令行参数list,第一个元素是元素本身路径
2 #sys.exit(n) 退出程序,正常退出时exit(0)
3 #sys.version 获取python解释程序的版本信息
4 #sys.maxint 最大的int值
5 #sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 #sys.platform 返回操作系统平台名称

【5】json模块:(任何语言都可以)

 1 import json
 2 dic={'name':'alex'}   #json会将所有的单引号变成双引号,json只认识双引号
 3 i=8
 4 data=json.dumps(dic)
 5 data1=json.dumps(i)
 6 print(data)
 7 print(data1)
 8 print(type(data))
 9 print(type(data1))
10 #结果:{"name": "alex"}     #变成json字符串
11 #      8
12 #      <class 'str'>
13 #      <class 'str'>
14 
15 在没有json之前,将一个字典存入一个文本,并且通过字典的键取值:
16 dic='{"name":"alex"}'
17 f=open('hello','w')
18 f.write(dic)
19 #将字典dic='{"name":"alex"}'已经以字符串的形式写入文本hello
20 f_read=open("hello","r")
21 data=f_read.read()
22 print(type(data))
23 data=eval(data)
24 print(data["name"])
25 #结果:<class 'str'>
26 #     alex
27 
28 使用json:
29 import json
30 dic={'name':'alex'}
31 dic_str=json.dumps(dic)
32 f=open("new_hello","w")
33 f.write(dic_str)
34 已经在new_hello这个文件里面将字典写入;
35 f_read=open("new_hello","r")
36 data=json.loads(f_read.read())
37 print(data["name"])
38 print(data)
39 print(type(data))
40 #结果:alex
41 #    {'name': 'alex'}
42 #    <class 'dict'>

【6】pickle模块:(与json一样,只不过json是字符串,而pickle是字节)

【7】shelve模块:(与json,pickle一样,也是进行数据传送的)

【8】XML模块:(XML是实现不同语言或者程序之间进行数据交换的协议,与json差不多)

 1 xml的格式如下,就是通过<>节点来区别数据结构的:
 2 <?xml version="1.0"?>
 3 <data>
 4     <country name="Liechtenstein">
 5         <rank updated="yes">2</rank>
 6         <year>2008</year>
 7         <gdppc>141100</gdppc>
 8         <neighbor name="Austria" direction="E"/>
 9         <neighbor name="Switzerland" direction="W"/>
10     </country>
11     <country name="Singapore">
12         <rank updated="yes">5</rank>
13         <year>2011</year>
14         <gdppc>59900</gdppc>
15         <neighbor name="Malaysia" direction="N"/>
16     </country>
17     <country name="Panama">
18         <rank updated="yes">69</rank>
19         <year>2011</year>
20         <gdppc>13600</gdppc>
21         <neighbor name="Costa Rica" direction="W"/>
22         <neighbor name="Colombia" direction="E"/>
23     </country>
24 </data>
xml格式
 1 利用xml格式里面的标签内容,取标签属性,内容等.....
 2 import xml.etree.ElementTree as ET
 3 
 4 tree = ET.parse("xml_lesson")  #parse解析
 5 root = tree.getroot()
 6 print(root.tag)   #打印root根结点的tag标签名data
 7 
 8 for i in root:
 9     print(i.tag)   #打印root后面标签的标签名country
10     print(i.attrib)   #打印属性,打印country的属性
11     for j in i:
12         print(j.tag)    #打印country后面标签的标签名...
13         print(j.attrib)   #打印属性
14         print(j.text)   #打印country里面标签的内容
15 
16 #结果:data
17 #country
18 #{'name': 'Liechtenstein'}
19 #rank
20 #{'updated': 'yes'}
21 #2
22 #year
23 #{}
24 #2008
25 #gdppc
26 #{}
27 #141100
28 #neighbor
29 #{'name': 'Austria', 'direction': 'E'}
30 #None
31 #neighbor
32 #{'name': 'Switzerland', 'direction': 'W'}
33 #None
34 #country
35 #{'name': 'Singapore'}
36 #rank
37 #{'updated': 'yes'}
38 #5
39 #year
40 #{}
41 #2011
42 #gdppc
43 #{}
44 #59900
45 #neighbor
46 #{'name': 'Malaysia', 'direction': 'N'}
47 #None
48 #country
49 #{'name': 'Panama'}
50 #rank
51 #{'updated': 'yes'}
52 #69
53 #year
54 #{}
55 #2011
56 #gdppc
57 #{}
58 #13600
59 #neighbor
60 #{'name': 'Costa Rica', 'direction': 'W'}
61 #None
62 #neighbor
63 #{'name': 'Colombia', 'direction': 'E'}
64 #None
 1 # 遍历xml文档
import xml.etree.ElementTree as ET

tree = ET.parse("xml_lesson") #parse解析
root = tree.getroot()

2 for child in root: 3 print('========>', child.tag, child.attrib, child.attrib['name']) 4 for i in child: 5 print(i.tag, i.attrib, i.text) 6 #结果:# ========> country {'name': 'Liechtenstein'} Liechtenstein 7 # rank {'updated': 'yes'} 2 8 # year {} 2008 9 # gdppc {} 141100 10 # neighbor {'name': 'Austria', 'direction': 'E'} None 11 # neighbor {'name': 'Switzerland', 'direction': 'W'} None 12 # ========> country {'name': 'Singapore'} Singapore 13 # rank {'updated': 'yes'} 5 14 # year {} 2011 15 # gdppc {} 59900 16 # neighbor {'name': 'Malaysia', 'direction': 'N'} None 17 # ========> country {'name': 'Panama'} Panama 18 # rank {'updated': 'yes'} 69 19 # year {} 2011 20 # gdppc {} 13600 21 # neighbor {'name': 'Costa Rica', 'direction': 'W'} None 22 # neighbor {'name': 'Colombia', 'direction': 'E'} None
 1 # 只遍历year 节点
 2 import xml.etree.ElementTree as ET
 3 
 4 tree = ET.parse("xml_lesson")  #parse解析
 5 root = tree.getroot()
 6 for node in root.iter('year'):
 7     print(node.tag, node.text)
 8 
 9 #结果:year 2008
10 #    year 2011
11 #    year 2011
 1#修改 2 import xml.etree.ElementTree as ET
 3 tree = ET.parse("xml_lesson")
 4 root = tree.getroot()
 5 
 6 
 7 for node in root.iter('year'):
 8     new_year = int(node.text) + 1  #年份增加1
 9     node.text = str(new_year)
10     node.set('updated', 'yes')   #新增加一个属性,updated=yes
11 tree.write('xml_lesson')
 1 # 删除node
 2 import xml.etree.ElementTree as ET
 3 
 4 tree = ET.parse("xml_lesson")
 5 root = tree.getroot()
 6 
 7 for country in root.findall('country'):
 8     rank = int(country.find('rank').text)   #在root的子节点找,只找一个
 9     if rank > 50:
10         root.remove(country)
11 
12 tree.write('output.xml')
 1 import xml.etree.ElementTree as ET
 2  
 3  
 4 new_xml = ET.Element("namelist")
 5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
 6 age = ET.SubElement(name,"age",attrib={"checked":"no"})
 7 sex = ET.SubElement(name,"sex")
 8 sex.text = '33'
 9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
10 age = ET.SubElement(name2,"age")
11 age.text = '19'
12  
13 et = ET.ElementTree(new_xml) #生成文档对象
14 et.write("test.xml", encoding="utf-8",xml_declaration=True)
15  
16 ET.dump(new_xml) #打印生成的格式
自己创建xml文档

【9】re模块:

      正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。就其本质而言,正则表达式是一种小型的,高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

  元字符:(模糊匹配)

 1 元字符:
 2 转义字符
 3 >>> import re
 4 >>> re.findall("I","I am LIST")
 5 ['I', 'I']
 6 >>> re.findall("^I","I am LIST")
 7 ['I']
 8 >>> re.findall("^I","hello I am LIST")
 9 []
10 >>> re.findall("I","hello I am LIST")   
11 []
12 >>> re.findall(r"I","hello I am LIST")
13 ['I']
14 #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义,传到re模块中。
15 >>> re.findall("I\b","hello I am LIST")
16 ['I']
17 >>>
18 >>> re.findall("c\f","abcferdv") 
19 ['cx0c']
20 #对于正则来说c\f确实可以匹配到cf,但是在python解释器读取c\f时,会发生转义,然后交给re去执行,所以抛出异常.
21 >>> re.findall("c\\f","abcferdv")
22 #四个\\先经过python解释器转义成两个\f传入re模块,转义成f匹配!!!
 1 元字符:
 2 或 a|b (匹配两个中的一个或者两个)
 3 >>>import re
 4 >>> re.findall(r"ka|b","sdkskaf")
 5 ['ka']
 6 >>> re.findall(r"ka|b","sdfkbx")
 7 ['b']
 8 >>> re.findall(r"ka|b","sdjka|bd")
 9 ['ka', 'b']
10 >>> re.findall(r"ka|am","sdka|amd")
11 ['ka', 'am']
12 >>> re.findall(r"ka|am","dfkaoamk")
13 ['ka', 'am']
 1 元字符:
 2 ()分组
 3 import re 
 4 >>> re.findall(r"(abc)+","abcabcabc")
 5 ['abc']
 6 >>> re.search("(?P<name>w+)","abcccc")
 7 <_sre.SRE_Match object; span=(0, 6), match='abcccc'>
 8 #固定分组,其实只有w+才有意义
 9 >>> re.search("d+","dsfgd23fv50").group()  #整数
10 '23'
11  #findall表示找所有,search表示找到一个就不会往下找了
12 >>> re.search("(?P<name>[a-z]+)","alex15dc2").group() #找a到z的字符串
13 'alex'
14 #.group()表示将结果显示出来
15 
16 >>> re.search("(?P<name>[a-z]+)","alex15dc2").group()
17 'alex'
18 >>>
19 >>> re.search("(?P<name>[a-z]+)d+","alex23zy18").group()
20 'alex23'
21 >>> re.search("(?P<name>[a-z]+)d+","alex23zy18").group("name")
22 'alex'
23 >>> re.search("(?P<name>[a-z]+)(?P<age>d+)","alex23zy18").group("age")
24 '23'
  1 元字符:
  2 一对一的匹配
  3 'hello'.replace(old,new)
  4 'hello'.find('pattern')
  5 
  6 正则匹配
  7 import re
  8 w与W
  9 print(re.findall('w','hello egon 123')) 
 10 #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
 11 print(re.findall('W','hello egon 123')) 
 12 #[' ', ' ']
 13 
 14 s与S
 15 print(re.findall('s','hello  egon  123'))
 16 #[' ', ' ', ' ', ' ']
 17 print(re.findall('S','hello  egon  123')) 
 18 #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
 19 
 20 
 	都是空,都可以被s匹配
 21 print(re.findall('s','hello 
 egon 	 123')) 
 22 #[' ', '
', ' ', ' ', '	', ' ']
 23 
 24  25 print(re.findall(r'
','hello egon 
123')) #['
']
 26 print(re.findall(r'	','hello egon	123')) #['
']
 27 
 28 d与D
 29 print(re.findall('d','hello egon 123')) 
 30 #['1', '2', '3']
 31 print(re.findall('D','hello egon 123')) 
 32 #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']
 33 
 34 A与
 35 print(re.findall('Ahe','hello egon 123')) 
 36 #['he']    A==>^
 37 print(re.findall('123','hello egon 123')) 
 38 #['he'],==>$
 39 
 40 ^与$
 41 print(re.findall('^h','hello egon 123')) #['h']
 42 print(re.findall('3$','hello egon 123')) #['3']
 43 
 44 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
 45 #.
 46 print(re.findall('a.b','a1b')) 
 47 #['a1b']
 48 print(re.findall('a.b','a1b a*b a b aaab')) 
 49 #['a1b', 'a*b', 'a b', 'aab']
 50 print(re.findall('a.b','a
b')) 
 51 #[]
 52 print(re.findall('a.b','a
b',re.S)) 
 53 #['a
b']
 54 print(re.findall('a.b','a
b',re.DOTALL)) 
 55 #['a
b']同上一条意思一样
 56 
 57 #*
 58 print(re.findall('ab*','bbbbbbb')) 
 59 #[]
 60 print(re.findall('ab*','a')) 
 61 #['a']
 62 print(re.findall('ab*','abbbb')) 
 63 #['abbbb']
 64 
 65 #?
 66 print(re.findall('ab?','a')) 
 67 #['a']
 68 print(re.findall('ab?','abbb')) 
 69 #['ab']
 70 #匹配所有包含小数在内的数字
 71 
 72 #.*默认为贪婪匹配
 73 print(re.findall('a.*b','a1b22222222b')) 
 74 #['a1b22222222b']
 75 
 76 #.*?为非贪婪匹配:推荐使用
 77 print(re.findall('a.*?b','a1b22222222b')) 
 78 #['a1b']
 79 
 80 #+
 81 print(re.findall('ab+','a')) 
 82 #[]
 83 print(re.findall('ab+','abbb')) 
 84 #['abbb']
 85 
 86 #{n,m}
 87 print(re.findall('ab{2}','abbb')) #['abb']
 88 print(re.findall('ab{2,4}','abbb')) #['abb']
 89 print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
 90 print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'
 91 
 92 #[]
 93 print(re.findall('a[1*-]b','a1b a*b a-b')) 
 94 #['a1b', 'a*b', 'a-b']
 95 #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
 96 print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) 
 97 #['a=b']
 98 #[]内的^代表的意思是取反,所以结果为['a=b']
 99 print(re.findall('a[0-9]b','a1b a*b a-b a=b')) 
100 #['a1b']
101 print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb'))
102 #['aeb']
103 print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) 
104 #['aeb', 'aEb']

   re模块之方法:

 1 re模块的方法:
 2 import re
 3 print(re.findall('e','alex make love') )   
 4 #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里
 5 
 6 print(re.search('e','alex make love').group()) 
 7 #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
 8 
 9 print(re.match('e','alex make love'))    
10 #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
11 >>>re.match("d+","15sfsdv").group()
12 '15'
13 
14 print(re.split('[ab]','abcd'))     
15 #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割
16 
17 print('===>',re.sub('a','A','alex make love')) 
18 #===> Alex mAke love,不指定n,默认替换所有
19 print('===>',re.sub('a','A','alex make love',1)) 
20 #===> Alex make love
21 print('===>',re.sub('a','A','alex make love',2)) 
22 #===> Alex mAke love
23 
24 >>>com=re.compile("d+")
25 >>>com.findall("dsgd12sfds32")
26 ['12','32']

【10】logging模块:

   日志级别:

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')
 
# WARNING:root:警告warn
# ERROR:root:错误error
# CRITICAL:root:严重critical
(默认级别为warning警告级别,默认打印到终端,所以只打印出来warning及以上的级别)

import logging

logging.basicConfig(level=logging.DEBUG)  #改变了最低级别为debug
logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

    为logging模块指定全局配置:(不常使用)

 1 可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,
 2 可用参数有:
 3 filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
 4 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
 5 format:指定handler使用的日志显示格式。 
 6 datefmt:指定日期时间格式。 
 7 level:设置rootlogger的日志级别。 
 8 stream:用指定的stream创建StreamHandler。可以指定输出sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
 9 
10 #格式
11 %(name)s:Logger的名字,并非用户名。
12 %(levelno)s:数字形式的日志级别
13 %(levelname)s:文本形式的日志级别
14 %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
15 %(filename)s:调用日志输出函数的模块的文件名
16 %(module)s:调用日志输出函数的模块名
17 %(funcName)s:调用日志输出函数的函数名
18 %(lineno)d:调用日志输出函数的语句所在的代码行
19 %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
20 %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
21 %(asctime)s:字符串形式的当前时间。默认格式是“2003-07-0816:49:45,896”。逗号后面的是毫秒
22 %(thread)d:线程ID。可能没有
23 %(threadName)s:线程名。可能没有
24 %(process)d:进程ID。可能没有
25 %(message)s:用户输出的消息

    logger:

 1 import logging
 2 
 3 logger=logging.getLogger()
 4 fh=logging.FileHandler('test_log')  #可以向文件里面发送日志
 5 ch=logging.StreamHandler() #可以向屏幕里面发送内容
 6 fm=logging.Formatter("%(asctime)s %(message)s")#定义日志格式,时间,信息
 7 fh.setFormatter(fm) #将格式给fh与ch
 8 ch.setFormatter(fm)
 9 logger.addHandler(fh) #将fh与ch给logger
10 logger.addHandler(ch)
11 logger.setLevel('DEBUG') #设置最低级别为DEBUG
12 
13 logger.debug('hello')
14 logger.info('hello')
15 logger.warning('hello')
16 logger.error('hello')
17 logger.critical('hello')
18 
19 #结果:2018-09-07 09:54:57,169 hello
20 #     2018-09-07 09:54:57,169 hello
21 #     2018-09-07 09:54:57,169 hello
22 #     2018-09-07 09:54:57,170 hello
23 #     2018-09-07 09:54:57,170 hello

【11】configparser模块:(配置文件)

首先,创建一个文档,text
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31

[section2]
k1 = v1
创建的text文档
 1 import configparser
 2 
 3 config=configparser.ConfigParser()
 4 config.read('a.cfg')  #读取刚创建的,a.cfg文档
 5 
 6 #查看所有的标题
 7 res=config.sections() 
 8 print(res)
 9 #['section1', 'section2']
10 
11 #查看标题section1下所有key=value的key
12 options=config.options('section1')
13 print(options) 
14 #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
15 
16 #查看标题section1下所有key=value的(key,value)格式
17 item_list=config.items('section1')
18 print(item_list) 
19 #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin','true'), ('salary', '31')]
20 
21 #查看标题section1下user的值   字符串格式
22 val=config.get('section1','user')
23 print(val) 
24 #egon
25 
26 #查看标题section1下age的值  整数格式
27 val1=config.getint('section1','age')
28 print(val1) 
29 #18
30 
31 #查看标题section1下is_admin的值  布尔值格式
32 val2=config.getboolean('section1','is_admin')
33 print(val2) 
34 #True
35 
36 #查看标题section1下salary的值  浮点型格式
37 val3=config.getfloat('section1','salary')
38 print(val3) 
39 #31.0
 1 增删改查:
 2 import configparser
 3 
 4 config=configparser.ConfigParser()
 5 config.read('a.cfg',encoding='utf-8')
 6 
 7 #删除整个标题section2
 8 config.remove_section('section2')
 9 
10 #删除标题section1下的某个k1和k2
11 config.remove_option('section1','k1')
12 config.remove_option('section1','k2')
13 
14 #判断是否存在某个标题
15 print(config.has_section('section1'))
16 
17 #判断标题section1下是否有user
18 print(config.has_option('section1',''))
19 
20 #添加一个标题
21 config.add_section('egon')
22 
23 #在标题egon下添加name=egon,age=18的配置
24 config.set('egon','name','egon')
25 config.set('egon','age',18) #报错,必须是字符串
26 
27 #最后将修改的内容写入文件,完成最终的修改
28 config.write(open('a.cfg','w'))

【12】hashlib模块:

             (主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法)

hash值的特点是:
1 只要传入的内容一样,得到的hash值必然一样(要用明文传输密码文件完整性校验)
2 不能由hash值返解成内容把密码做成hash值,不应该在网络传输明文密码)
3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
 1 import hashlib
 2 obj=hashlib.md5()   #md5与sha256用法一样
 3 obj.update("hello".encode("utf-8"))
 4 print(obj.hexdigest())
 5 #5d41402abc4b2a76b9719d911017c592
 6 
 7 #(1)一段字符串可以转换成一段密文,且不能反解
 8 #(2)不能反解,但可以明文转换成密文后进行比较
 9 #(3)再加一段字符串,这种对应关系不可能被别人反解
10 import hashlib
11 obj=hashlib.md5("dsgzhbghf".encode('utf8'))
12 obj.update("hello".encode("utf-8"))
13 print(obj.hexdigest())
14 #d3edeba44299777b366df4bfd06f164c
15 
16 import hashlib
17 obj=hashlib.md5()
18 obj.update("hello".encode("utf-8"))
19 print(obj.hexdigest())
20 obj.update("root".encode("utf-8"))
21 print(obj.hexdigest())
22 #5d41402abc4b2a76b9719d911017c592
23 #e206121dbbe984f3bc6c6448846ed8cd(与helloroot加密结果一样)
原文地址:https://www.cnblogs.com/zhouyuan666/p/9549269.html