Python-模块

一、模块:

  Python中的模块,就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包好可执行的代码。

  文件名就是模块名加上后缀.py,在模块内部,模块名存储在全局变量__name__中,是一个string,可以直接在模块中通过__name__引用到模块名。

  模块分为三类:

    -- 自定义模块

    -- 内置模块

    -- 第三方模块

  导入模块:

    -- import:使导入者以一个整体获取一个模块

    -- from:使导入者从一个模块文件中获取特定的变量名

    -- reload:在不终止Python程序的情况下,提供了一个重新载入模块文件代码的方法

  导入模块的方法:

 1 import module # 会先把module执行一遍(如果里边有可执行程序)
 2 from module.xxx.xxx import xx
 3 from module.xxx.xxx import xx as rename
 4 from module.xxx.xxx import *   # 不推荐使用,因为里边可能有一些代码,跟执行文件里自定义的可执行代码重复,导致覆盖
 5 
 6 
 7 正确的调用方式:
 8 
 9 import cal #当前目录直接调用模块
10 
11 from my_module import cal  # 二层目录调用
12 
13 from web1.web2.web3 import cal  # 多层目录调用
14 
15 from web1.web2.web3.cal import add # 只调用某个方法
16 
17 
18 
19 注意:不支持的调用方式  (调用包就是执行包下的__init__.py文件)
20 from web1.web2 import web3  #这样是执行web3的__init__文件,唯一不支持的调用方式
21 print(web3.cal.add(2,6))

 

  获取模块的路径:

 1 import sys
 2 print(sys.path)
 3 
 4 添加路径:
 5 
 6 import sys
 7 import os
 8 # project_path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 9 # sys.path.append(project_path)
10 print(os.path.abspath(__file__)) # 是获取的文件名,路径是pycharm加上的
11 print(os.path.dirname(os.path.abspath(__file__))) # 获取文件的路径
12 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) #获取上一层目录

 

  第三方模块:

 1 #先安装 gcc 编译和 python 开发环境
 2 yum install gcc
 3 yum install python-devel
 4  5 apt-get python-dev
 6  
 7 #安装方式(安装成功后,模块会自动安装到 sys.path 中的某个目录中)
 8 yum
 9 pip
10 apt-get
11 ...
12 #进入python环境,导入模块检查是否安装成功
第三方模块(linux)

 

二、包(package)

  如果不同的人编写的代码模块名相同怎么办?为了避免冲突,Python引入了按目录来组织模块的方法,称为包。

  

  如图所示,两个cal.py冲突了,但是功能不同,所以给两个模块选择一个顶层包(不能重名),在调用就不会冲突了。

  --注--:

    请注意:每个包目录下来都会有一个__init__.py的文件,这个文件必须是存在的,否则,Python就不把这个目录当成普通目录,而不是一个包,__init__.py可以是空文件,也可以有python代码,__init__.py本身就是一个文件,它的模块名就是对应的包名,它一般由于做接口文件。

    调用包就是执行包下的__init__.py文件

三、time模块  

1 时间有三种表达方式:
2 
3 时间戳: unix元年到现在------>time.time()
4 格式化的字符串:如:2016-12-12 10:10------->time.strftime('%Y-%m-%d')
5 结构化时间:元组 ------>time.struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)    即:time.localtime()

 

  

 1 import time
 2 
 3 # 1、时间戳
 4 print(time.time())
 5 
 6 # 2、localtime()
 7 print(time.localtime())  # 空参
 8 ##time.struct_time(tm_year=2016, tm_mon=9, tm_mday=11, tm_hour=0, tm_min=38, tm_sec=39, tm_wday=6, tm_yday=255, tm_isdst=0)
 9 
10 print(time.localtime(1422222222)) # 指定时间戳
11 
12 # 3、gmtime()
13 print(time.gmtime()) # gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
14 
15 
16 # 4、mktime()
17 print(time.mktime(time.loacltime())) #将结构化时间转换为时间戳
18 
19 # 5、asctime()
20 print(time.asctime()) # 将结构化时间转变为:'Sun Jun 20 23:21:05 1993'
21 默认参数是time.localtime()
22 
23 # 6、ctime()
24 print(timectime()) #将时间戳转化为:'Sun Jun 20 23:21:05 1993'
25 默认参数是time.time()
26 
27 # 7、strftime()
28 print(time.strftime(format[,t])) #结构化时间转化为 字符串时间
29 默认参数time.localtime()
30 print(time.strftime('%Y-%m-%d %X',time.localtime())) # 2018-03-26 19:11:36
31 
32 # 8、strptime()
33 print(time.strptime())# 字符串时间转化为结构化时间
34 print(time.strptime('2016:12:23:17:20:20','%Y:%m:%d:%X')) # time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=17, tm_min=20, tm_sec=20, tm_wday=4, tm_yday=358, tm_isdst=-1)
35 
36 # 9、sleep()
37 
38 # 10、clock()
39 这个需要注意,在不同的系统上含义不同。
40 在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。
41 而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间,即两次时间差

 

        记住如下图即可:

 

    ---注---    

1 import datetime
2 print(datetime.datetime.now())
3 ##2018-03-27 17:47:07.211182

四、random模块  

  随机数模块:

 1 import random
 2  
 3 print(random.random())          #用于生成一个0到1的随机符点数: 0 <= n < 1.0
 4 print(random.randint(1,2))      #用于生成一个指定范围内的整数 [1,2]
 5 print(random.randrange(1,10))   #从指定范围内,按指定基数递增的集合中获取一个随机数 [1,10)
 6 print(random.uniform(1,10))     #用于生成一个指定范围内的随机符点数 9.49909962942907
 7 print(random.choice('nick'))    #从序列中获取一个随机元素 c
 8 li = ['nick','jenny','car',]
 9 random.shuffle(li)              #用于将一个列表中的元素打乱
10 print(li)
11 li_new = random.sample(li,2)    #从指定序列中随机获取指定长度的片断(从li中随机获取2个元素,作为一个片断返回)
12 print(li_new)

   示例:验证码  查看:http://www.cnblogs.com/JerryZao/p/8659024.html

 五、os模块

  os模块是与操作系统交互的一个接口 

 1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
 2 os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
 3 os.curdir  返回当前目录: ('.')
 4 os.pardir  获取当前目录的父目录字符串名:('..')
 5 os.makedirs('dirname1/dirname2')    可生成多层递归目录
 6 os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
 7 os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
 8 os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
 9 os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
10 os.remove()  删除一个文件
11 os.rename("oldname","newname")  重命名文件/目录
12 os.stat('path/filename')  获取文件/目录信息
13 os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
14 os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
15 os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
16 os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
17 os.system("bash command")  运行shell命令,直接显示
18 os.environ  获取系统环境变量
19 os.path.abspath(path)  返回path规范化的绝对路径
20 os.path.split(path)  将path分割成目录和文件名二元组返回
21 os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
22 os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
23 os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
24 os.path.isabs(path)  如果path是绝对路径,返回True
25 os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
26 os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
27 os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
28 os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
29 os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

 

  ps1、os.stat() 

 1 stat 结构:
 2 
 3 st_mode: inode 保护模式
 4 st_ino: inode节点号。
 5 st_dev: inode驻留的设备。
 6 st_nlink: inode 的链接数。
 7 st_uid: 所有者的用户ID。
 8 st_gid: 所有者的组ID。
 9 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
10 st_atime: 上次访问的时间。
11 st_mtime: 最后一次修改的时间。
12 st_ctime: 创建时间,由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。

 

六、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       返回操作系统平台名称
1 import time sys
2 
3 for i in range(100):
4     sys.stdout.write("*")
5     time.sleep(1)
6     sys.stdout.flush()
进度条

 

七、json 和 pickle模块

  用于序列化的两个模块;

    json:用于字符串和Python数据类型间的进行转换

    pickle:用于Python特有的类型 和P一条红的数据类型间的转换 

    之前学过eval内置方法,可以将字符串转换为python对象,但是局限性很大,一般eval只用于字符串表达式。

  什么是序列化:

    我们把对象(变量)从内存中变为可存储或可传输的过程称之为序列化。

    序列化之后,就可以吧序列化后的内容写入磁盘,或者通过网络传输到别的机器上

  json模块 提供了四个功能:dumps  dump  loads load

  pickle模块也是一样的四个功能。

    dump() 函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存到给定的文件中,当我们使用load()函数从文件中读取已保存的对象时,picle知道如何恢复这些对象到他们本来的格式

    dumps() 函数执行和dump() 函数相同的序列化,取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据

    loads() 函数执行和load() 函数一样的反序列化,取代接受一个流对象并去文件都序列化后的数据,它就收包含序列化后的数据的str对象,直接返回的对象

         

  eval()方法:

    1、

1 import json
2 
3 dic = '{"jakc":12}' 
4 f = open('c.txt','w')
5 f.write(dic)

    2、

1 f = open('c.txt','r')
2 data = f.read()
3 print(type(data))
4 data1 = eval(data)
5 print(data1['jakc'])

  json模块:

    1、把字典转换成json形式的字符串写入文件中 (两种方法效果一样,只是写法不同而已)

 1 #-----------方法一--------推荐使用
 2 
 3 dic = {'age':12}
 4 dic = json.dumps(dic)
 5 print(dic) # {"age": 12} 内部都是用双引号,json格式
 6 f = open('c.txt','w')
 7 f.write(dic)
 8 f.close()
 9 
10 #-----------方法二
11 
12 dic = {'age':13}
13 f = open('d.txt','w')
14 json.dump(dic,f)

 

    2、json反序列化 

 1 把文件中json类型的字符串读取出来转换成字典
 2 
 3 #------------------方法一---推荐
 4 f = open('d.txt','r')
 5 a = json.loads(f.read())
 6 print(a)
 7 print(type(a))
 8 
 9 #------------------方法二
10 f = open('c.txt','r')
11 b = json.load(f)
12 print(b)
13 print(type(b))

 

   --注---

1 import json
2 #dct="{'1':111}"#json 不认单引号
3 #dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}
4 
5 dct='{"1":"111"}'
6 print(json.loads(dct))
7 
8 #conclusion:
9 #        无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

 

  

json的dumps,loads,dump,load功能总结:

json.dumps(x)    把python的(x)原对象转换成json字符串的对象,主要用来写入文件。

json.loads(f)       把json字符串(f)对象转换成python原对象,主要用来读取文件和json字符串

json.dump(x,f)  把python的(x)原对象,f是文件对象,写入到f文件里面,主要用来写入文件的

json.load(file)  把json字符串的文件对象,转换成python的原对象,只是读文件

  pickle模块

     pickle转换后的结果是bytes    

1 pickle序列化:
2 
3 dic = {'name':'jakc','age':12}
4 j = pickle.dumps(dic)
5 f = open('e.txt','wb')
6 f.write(j)    # 等价pickle.dump(fic,f)
7 f.close()

 

1 pickle反序列化:
2 
3 f = open('e.txt','rb')
4 data = pickle.loads(f.read()) # 等价 data = pickle.load(f)
5 print(data)

 

  Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

八、shelve模块

  shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写,key必须是字符串

# 添加键值对到文件中,会生成三个文件,并写入字典内容

import shelve

f = shelve.open(r'sssss') # 目的:将一个字典写入文本 f={}
print(f)
f['a1']= {'name':'alex','age':12}
f['a2']= {'name':'jakc','age':12}
f['b1']= {'a':'aa','b':'bb'}
f.close()




-----------------------------------------------------------------------------
会生成三个文件:sssss.dat,sssss.dir,sssss.bak,其中sssss.bak中内容如下:
'a1', (0, 42)
'a2', (512, 42)
'b1', (1024, 42)

 

1 # 取值:
2 
3 f = shelve.open(r'sssss')
4 print(f.get('a1')['name'])

 

九、xml模块

  xml 是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但是json简单。

  xml的格式如下:

 1 <?xml version="1.0"?>
 2 <data>   #根
 3     <country name="Liechtenstein">  #节点
 4         <rank updated="yes">2</rank>
 5         <year>2008</year>
 6         <gdppc>141100</gdppc>
 7         <neighbor name="Austria" direction="E"/>  
 8         <neighbor name="Switzerland" direction="W"/>  
 9     </country>
10     <country name="Singapore">     #节点
11         <rank updated="yes">5</rank>
12         <year>2011</year>
13         <gdppc>59900</gdppc>
14         <neighbor name="Malaysia" direction="N"/>
15     </country>
16     <country name="Panama">      #节点
17         <rank updated="yes">69</rank>
18         <year>2011</year>
19         <gdppc>13600</gdppc>
20         <neighbor name="Costa Rica" direction="W"/>
21         <neighbor name="Colombia" direction="E"/>
22     </country>
23 </data>
24 
25 xml数据
样例

  xml在各个语言里都是支持的,在python中可以使用xml模块操作xml文件 。

 1 # 基本操作1:
 2 
 3 import xml.etree.ElementTree as ET
 4 
 5 tree = ET.parse("test.xml") # 获取一个xml文件对象
 6 root = tree.getroot()
 7 print(root.tag) # 获取跟节点的标签 data
 8 
 9 遍历xml文档
10 for i in root:
11     print(i.tag,i.attrib) # 根节点下的标签,一级属性名,属性值
12     for j in i:
13         print(j.tag,j.attrib) # 在往下一层的节点,和属性
14 
15 只遍历year节点
16 for i in root.iter('year'):
17     print(i.tag,i.text)
18 
19 ----->
20 year 2008
21 year 2011
22 year 2011

 

 1 # 基本操作2:
 2 
 3 import xml.etree.ElementTree as ET
 4 
 5 tree = ET.parse("test.xml") # 获取一个xml文件对象
 6 root = tree.getroot()
 7 
 8 # 修改
 9 for i in root.iter('year'):
10     print(i)
11     new_year = int(i.text) + 1
12     i.text = str(new_year)
13     i.set('update','yes') # 增加一个属性
14 
15 tree.write('new_test.xml') # 将内存中修改后的,写到文件中,也可以直接写到原文件中覆盖
16 
17 # 删除节点
18 for i in root.findall('country'): # 找到所有的country
19     rank = int(i.find('rank').text)# 某个country下找rank
20     if rank > 50:
21         root.remove(i)  # 删除符合条件的节点
22 
23 tree.write('new_test2.xml')

 

  如何自己创建一个xml文档:

 1 import xml.etree.ElementTree as ET  # as后面的ET是前面的类的别名,名称随便取
 2 
 3 new_xml = ET.Element("namelist")
 4 name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
 5 
 6 age = ET.SubElement(name, "age", attrib={"checked": "no"})
 7 sex = ET.SubElement(name, "sex")
 8 sex.text = '33'
 9 
10 name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
11 
12 age = ET.SubElement(name2, "age")
13 age.text = '19'
14 
15 # 不懂记住就行
16 et = ET.ElementTree(new_xml)  # 生成文档对象  (记住重点)
17 et.write("test.xml", encoding="utf-8", xml_declaration=True) # (记住重点)
18 
19 ET.dump(new_xml)  # 打印生成的格式

 

十、configparser模块

  用来处理配置文件的

  1、配置文件格式:

 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

 

  2、写一个配置文件

 1 import configparser
 2 
 3 config = configparser.ConfigParser()     #config={}
 4 
 5 config["DEFAULT"] = {'ServerAliveInterval': '45',
 6                      'Compression': 'yes',
 7                      'CompressionLevel': '9'}
 8 
 9 with open('example1.ini', 'w') as f:
10     config.write(f)
11 
12 
13 ---------> 生成example.ini文件
14 
15 [DEFAULT]
16 compressionlevel = 9
17 compression = yes
18 serveraliveinterval = 45

 

  3、生成一个多键值对的配置文件

 1 import configparser
 2 
 3 config = configparser.ConfigParser()     #config={}
 4 
 5 config["DEFAULT"] = {'ServerAliveInterval': '45',
 6                      'Compression': 'yes',
 7                      'CompressionLevel': '9'}
 8 
 9 config['bitbucket.org'] = {}
10 config['bitbucket.org']['User'] = 'hg'
11 
12 config['topsecret.server.com'] = {}
13 topsecret = config['topsecret.server.com']
14 topsecret['Host Port'] = '50022'      # mutates the parser
15 topsecret['ForwardX11'] = 'no'        # same here
16 
17 with open('example1.ini', 'w') as f:
18     config.write(f)
19 
20 
21 
22 -------------->
23 
24 #会生成example1.ini文件,内容如下:
25 
26 [DEFAULT]
27 compression = yes
28 compressionlevel = 9
29 serveraliveinterval = 45
30 
31 [bitbucket.org]
32 user = hg
33 
34 [topsecret.server.com]
35 host port = 50022
36 forwardx11 = no

 

  4、对配置文件实现查询功能:

    4.1、找出相应的值

1 import configparser
2 
3 config = configparser.ConfigParser() # config对象
4 config.read('example.ini')
5 print(config['bitbucket.org']['User']) # 不区分大小写  输出 hg

    4.2、如果去bitbucket.org键的值,它会把DEFAULT的一起打印出来,DEFAULT的特殊功能:因为只要带DEFAULT键值对的,他就会把DEFAULT的键打印出来

 1 config = configparser.ConfigParser()
 2 config.read('example.ini')
 3 
 4 for key in config['bitbucket.org']:
 5     print(key)
 6 
 7 -------->输出
 8 
 9 user
10 compression
11 compressionlevel
12 serveraliveinterval

    4.3、取的是bitbucket.org键的值,以列表的方式打印出来

1 config = configparser.ConfigParser()
2 config.read('example.ini')
3 print(config.options('bitbucket.org'))
4 
5 #['user', 'compression', 'compressionlevel', 'serveraliveinterval']

 

’    4.4、取的是bitbucket.org键和值,以元组的方式打印出来

1 import configparser
2 
3 config = configparser.ConfigParser()
4 config.read('example1.ini')
5 print(config.items('bitbucket.org')) 

-------> 输出

1 [('compression', 'yes'), ('compressionlevel', '9'),('serveraliveinterval', '45'), ('user', 'hg')]

    4.5、连续取值,取出compression的值

1 import configparser
2 
3 config = configparser.ConfigParser()
4 config.read('example.ini')
5 
6 print(config.get('bitbucket.org','compression'))   #取出compression的值 yes
7 print(config.get('bitbucket.org','user'))   #取出compression的值 hg

  5、增加功能:

    实现:在example1.txt文件中读取原来块的内容,增加一个新的块

 1 import configparser
 2 
 3 config = configparser.ConfigParser()
 4 config.read('example.ini')
 5 
 6 config.add_section('jerry') #添加一个快
 7 config.set('jerry','key','zao') #添加键值
 8 
 9 
10 config["DEFAULT2"] = {'ServerAliveInterval': '45', # 直接用创建example.ini的方法也可以
11                      'Compression': 'yes',
12                      'CompressionLevel': '9'}
13 
14 config.write(open('example.ini','w')) #写入 新文件 并覆盖

  6 、删除

1 import configparser
2 
3 config = configparser.ConfigParser()
4 config.read('example.ini')
5 config.remove_section('DEFAULT2') # 删除整个块
6 config.remove_option('jerry','key') # 删除块下的一对键值
7 config.write(open('example.ini','w'))

 

十一、logging模块

  1、简单显示:

import logging  

logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')


-------------->输出:默认级别是warning ,debug级别最低,只显示默认级别以及高级别的


1 WARNING:root:warning message
2 ERROR:root:error message
3 CRITICAL:root:critical message 

 

  2、给logging加上参数,并保存到一个文件中

 1 import logging
 2 logging.basicConfig(
 3 
 4     level= logging.DEBUG, # 默认级别
 5     filename='logger.log', # 保存为什么名字
 6     filemode='w',# 每次只写5条记录,默认是追加模式
 7     format = '%(asctime)s %(filename)s [%(lineno) d] %(message)s' #asctime 时间,lineno 行号,message 信息,还可以加其它信息参数
 8 )
 9 
10 logging.debug('debug message')
11 logging.info('info message')
12 logging.warning('warning message')
13 logging.error('error message')
14 logging.critical('critical message')
15 
16 
17 -------------->输出
18 
19 
20 2018-03-29 11:41:17,742 logging模块.py [ 10] debug message
21 2018-03-29 11:41:17,787 logging模块.py [ 11] info message
22 2018-03-29 11:41:17,787 logging模块.py [ 12] warning message
23 2018-03-29 11:41:17,787 logging模块.py [ 13] error message
24 2018-03-29 11:41:17,787 logging模块.py [ 14] critical message

 

  --注--    

可见在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。 
datefmt:指定日期时间格式。 
level:设置rootlogger(后边会讲解具体概念)的日志级别 
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中可能用到的格式化串:
%(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用户输出的消息

  3、自定义日志格式(重点)

  上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式
(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数
是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)

    3.1、示例,自定义一个日志

 1 import logging
 2 
 3 logger = logging.getLogger() # 创建一个root根对象
 4 
 5 fh = logging.FileHandler('test_log') #定义一个文件,并用于保存内容
 6 ch = logging.StreamHandler() # 将内容发送到屏幕
 7 
 8 fm = logging.Formatter("%(asctime)s  %(message)s") # 设置日志格式
 9 
10 fh.setFormatter(fm)  # 将设置的格式,用到文件中
11 ch.setFormatter(fm) # 将设置的格式用于屏幕打印中
12 
13 logger.addHandler(fh) # 吸收fh,将fh吃掉
14 logger.addHandler(ch)
15 
16 logger.debug("debug")   #输出日志的级别
17 logger.info("info")
18 logger.warning("warning")
19 logger.error("error")
20 logger.critical("critical")

 

    3.2、logger.setLevel("DEBUG")   调整日志级别,控制日志显示信息,DEBUG显示5条记录

   1 import logging
 2 
 3 import logging
 4 
 5 logger=logging.getLogger()         #创建一个大对象
 6 
 7 fh=logging.FileHandler("test_log") #向文件里发送内容,并且给个参数,作用是:定义一个文件名,往文件里写入内容
 8 ch=logging.StreamHandler()         #向屏幕上发送内容
 9 
10 fm=logging.Formatter("%(asctime)s  %(message)s")   #这个也是一个对象,作用是:定义日志格式
11 
12 fh.setFormatter(fm)      #往文件里写内容
13 ch.setFormatter(fm)      #往屏幕上输出内容
14 
15 logger.addHandler(fh)    #对象,类似于吸别人内力,把fh吃掉
16 logger.addHandler(ch)    #对象,类似于吸别人内力,把ch吃掉
17 logger.setLevel("DEBUG") #设置日志级别,控制日志输入多少条信息
18 
19 
20 #-------------从这里开始都是在操作log----------------
21 
22 logger.debug("debug")   #输出日志的级别
23 logger.info("info")
24 logger.warning("warning")
25 logger.error("error")
26 logger.critical("critical")

 

    3.3、写成函数的形式,并有返回值

 1 import logging
 2 
 3 def logger():
 4 
 5     logger=logging.getLogger()         #创建一个大对象
 6 
 7     fh=logging.FileHandler("test_log") #向文件里发送内容,并且给个参数,作用是:定义一个文件名,往文件里写入内容
 8     ch=logging.StreamHandler()         #向屏幕上发送内容
 9 
10     fm=logging.Formatter("%(asctime)s  %(message)s")   #这个也是一个对象,作用是:定义日志格式
11 
12     fh.setFormatter(fm)       #往文件里写内容
13     ch.setFormatter(fm)       #往屏幕上输出内容
14 
15     logger.addHandler(fh)     #对象,类似于吸别人内力,把fh吃掉
16     logger.addHandler(ch)     #对象,类似于吸别人内力,把ch吃掉
17     logger.setLevel("DEBUG")  #设置日志级别,控制日志输入多少条信息
18 
19     return logger
20 
21 #-------------从这里开始都是在操作log----------------
22 logger=logger()         #这个日志就做成了一个接口,想在其它地方使用,直接调用他就可以啦!
23 
24 logger.debug("debug")   #输出日志的级别
25 logger.info("info")
26 logger.warning("warning")
27 logger.error("error")
28 logger.critical("critical")

    3.4、没有root用户,创建两个logger对象

 1 import logging
 2 
 3 logger1 = logging.getLogger('mylogger')   #默认是根,这里代表他是子用户(两个用户是同级)
 4 #logger1 = logging.getLogger('mylogger.sontree')   #如果mylogger下再创建一个字对象,就用.sontree;等于他就是mylogger的下级对象。
 5 logger1.setLevel(logging.DEBUG)           #第一次是DEBUG级别
 6 
 7 logger2 = logging.getLogger('mylogger')   #默认是根,这里代表他是子用户(两个用户是同级)
 8 logger2.setLevel(logging.INFO)            #第二次是INFO级别,覆盖第一次的级别,所以打印结果是INFO级别显示
 9 
10 fh=logging.FileHandler("test_log-new")    #向文件里发送内容,并且给个参数,作用是:定义一个文件名,往文件里写入内容
11 ch=logging.StreamHandler()                #向屏幕上发送内容
12 
13 logger1.addHandler(fh)
14 logger1.addHandler(ch)
15 
16 logger2.addHandler(fh)
17 logger2.addHandler(ch)

 

 1 -----------------------》文件和屏幕
 2 logger1 and logger2各打印4条信息
 3 生成一个test_log-new的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
 4 文件内容如下:
 5 logger1 info message
 6 logger1 warning message
 7 logger1 error message
 8 logger1 critical message
 9 logger2 info message
10 logger2 warning message
11 logger2 error message
12 logger2 critical message
13 
14 #屏幕上面显示的内容
15 logger1 info message
16 logger1 warning message
17 logger1 error message
18 logger1 critical message
19 logger2 info message
20 logger2 warning message
21 logger2 error message
22 logger2 critical message

 

    PS:根据以上结果,可以知道,在同一个根下,不能创建两个名字一样的子根

 

    3.5、添加根用户(logger和mylogger是父子关系),注意日志输出问题

 1 import logging
 2 
 3 logger = logging.getLogger()              #根用户(根用户级别,没有定义日志级别,默认warning级别,所以是3条信息
 4 
 5 logger1 = logging.getLogger('mylogger')   #默认是根,这里代表他是子用户(两个用户是同级)
 6 logger1.setLevel(logging.DEBUG)           #第一次是DEBUG级别,默认是打印五条信息,但是他打印信息的时候,会先去找父,如果有父,他就会多打印一遍,所以输出是10条信息
 7 
 8 fh=logging.FileHandler("test_log-new")    #向文件里发送内容,并且给个参数,作用是:定义一个文件名,往文件里写入内容
 9 ch=logging.StreamHandler()                #向屏幕上发送内容
10 
11 logger.addHandler(ch)                     #添加一个根用户
12 logger.addHandler(fh)
13 
14 logger1.addHandler(fh)                    #添加一个子用户
15 logger1.addHandler(ch)
16 
17 #打印信息
18 logger.debug('logger debug message')
19 logger.info('logger info message')
20 logger.warning('logger warning message')
21 logger.error('logger error message')
22 logger.critical('logger critical message')
23 
24 #打印4条信息
25 logger1.debug('logger1 debug message')
26 logger1.info('logger1 info message')
27 logger1.warning('logger1 warning message')
28 logger1.error('logger1 error message')
29 logger1.critical('logger1 critical message')

 

 1 ---------------->输出
 2 
 3 生成一个test_log-new的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
 4 文件内容如下:
 5 logger warning message
 6 logger error message
 7 logger critical message    #前三条是根输出的三条信息
 8 logger1 debug message      #后10条是子输出的10条信息,为什么会输入10条呢?
 9 logger1 debug message      #第一次是DEBUG级别,默认是打印五条信息,但是他打印信息的时候,会先去找父,如果有父,他就会多打印一遍,所以输出是5+5=10条信息
10 logger1 info message
11 logger1 info message
12 logger1 warning message
13 logger1 warning message
14 logger1 error message
15 logger1 error message
16 logger1 critical message
17 logger1 critical message
18 
19 屏幕输出内容如下:
20 logger warning message
21 logger error message
22 logger critical message    
23 logger1 debug message
24 logger1 debug message
25 logger1 info message
26 logger1 info message
27 logger1 warning message
28 logger1 warning message
29 logger1 error message
30 logger1 error message
31 logger1 critical message
32 logger1 critical message

 

    PS:以上结果可以看到,有root根handler输出时,root的下一层,既会将消息分发给他的handler进行处理也会传递给所有的祖先Logger处理

十二、hashlib模块

hashlib 明文变成密文,不能反解
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

md5算法 明文变成密文

 1 import hashlib
 2 
 3 obj = hashlib.md5()
 4 obj.update('jerry'.encode('utf-8'))
 5 print(obj.hexdigest()) # 30035607ee5bb378c71ab434a6d05410 32位
 6 
 7 -------------------------------------------------------------------------
 8 import hashlib
 9 
10 #md5加密+字符串,给元字符串加盐
11 obj=hashlib.md5("sssdsdsb".encode("utf8"))   #在md5里面加点字符串,再生成,就没法破解
12 obj.update("admin".encode("utf8"))
13 
14 print(obj.hexdigest())
15 
16 -------------------------------------------------------------------------
17 python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密:
18 import hmac
19 h = hmac.new('jerry'.encode('utf-8'))
20 h.update('hello'.encode('utf-8'))
21 print(h.hexdigest())

 

posted @ 2018-03-27 18:02  JerryZao  阅读(241)  评论(0编辑  收藏  举报