码迷,mamicode.com
首页 > 编程语言 > 详细

python基础07

时间:2018-06-01 23:23:20      阅读:365      评论:0      收藏:0      [点我收藏+]

标签:日志输出   present   ec2   python基础   archive   精简   %s   存在   web   

Python基础学习07-模块


模块


一、模块基础

1、定义

模块:用来从逻辑上组织python代码(变量、函数、类、逻辑:目的是实现一个功能 ),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test)

包:用来从逻辑上组织模块的,本质就是一个目录(必须带有一个__init__.py的文件)

 2、导入方法

import  module_name (导入一个模块)

import  module_name_1,module_name_2(导入多个模块用逗号分隔)

from module_name  import  *  (导入模块内的全部方法、变量、函数)

from module_name  import  logger  as  logger_module  (当导入模块中的函数或变量与本模块中的函数或变量冲突时用as重命名)

3、import的本质:

import 模块的本质:

import  module_name  其本质是:将module_name.py文件解释运行了一遍,并把这个模块运行的结果赋值给了module_name这个变量

from module_name  import  x  其本质是:将 module_name.py中的代码里的x变量,放到了当前位置,执行了一遍

导入模块的本质就是找到模块并把python文件解释一遍

import  module_name,一定要找到一个名为module_name.py的文件,找文件一定要知道文件夹路径(一般默认查找:当前路径、sys.path)

import os 

os.path.abspath(__file__)  #获取当前文件的绝对路径

os.path.dirname(os.path.abspath(__file__))  #获取当前文件的目录名

os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  #获取上一级目录名

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))    #追加到环境变量列表的结尾

import 包的本质:

导入包的本质就是找到包执行该包下的__init__.py文件

import  package   #相当于run __init__.py  因此若想导入一个包下的模块,需要修改这个包的__init__.py文件

#在__init__.py文件中from .  import  module_name 

模块的分类:

a、标准库:内置模块,python解释器自带,拿过来就用

b、开源模块:第三方模块

c、自定义模块:自己定义的模块

二、内置模块

1、time与datetime模块 

在Python中,通常有这几种方式来表示时间:

a、格式化的时间字符串(Format String)

b、时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。

c、结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

技术分享图片
1 import time
2 print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:2018-05-24 20:48:10
3 print(time.time()) # 时间戳:1527166090.1953392
4 print(time.localtime()) #本地时区的struct_time:time.struct_time(tm_year=2018, tm_mon=5, tm_mday=24, tm_hour=20, tm_min=48, tm_sec=10, tm_wday=3, tm_yday=144, tm_isdst=0)
5 print(time.gmtime())    #UTC时区的struct_time:time.struct_time(tm_year=2018, tm_mon=5, tm_mday=24, tm_hour=12, tm_min=48, tm_sec=10, tm_wday=3, tm_yday=144, tm_isdst=0)
View Code
技术分享图片
 1 %a    Locale’s abbreviated weekday name.     
 2 %A    Locale’s full weekday name.     
 3 %b    Locale’s abbreviated month name.     
 4 %B    Locale’s full month name.     
 5 %c    Locale’s appropriate date and time representation.     
 6 %d    Day of the month as a decimal number [01,31].     
 7 %H    Hour (24-hour clock) as a decimal number [00,23].     
 8 %I    Hour (12-hour clock) as a decimal number [01,12].     
 9 %j    Day of the year as a decimal number [001,366].     
10 %m    Month as a decimal number [01,12].     
11 %M    Minute as a decimal number [00,59].     
12 %p    Locale’s equivalent of either AM or PM.    (1)
13 %S    Second as a decimal number [00,61].    (2)
14 %U    Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0.    (3)
15 %w    Weekday as a decimal number [0(Sunday),6].     
16 %W    Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.    (3)
17 %x    Locale’s appropriate date representation.     
18 %X    Locale’s appropriate time representation.     
19 %y    Year without century as a decimal number [00,99].     
20 %Y    Year with century as a decimal number.     
21 %z    Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].     
22 %Z    Time zone name (no characters if no time zone exists).     
23 %%    A literal % character.
格式化字符串的时间格式

 time模块

技术分享图片

技术分享图片
 1 import time
 2 print(time.time())   #获取时间戳:1527167372.0
 3 time.sleep(0.1)  #休眠0.1s
 4 
 5 print(time.gmtime(1527167372.0))  #将时间戳转换为结构化的时间:(转换成的是utc时区的时间)如果参数未提供,则以当前时间为准
 6 # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=24, tm_hour=13, tm_min=9, tm_sec=32, tm_wday=3, tm_yday=144, tm_isdst=0)
 7 print(time.localtime(1527167372.0)) # #将时间戳转换为结构化的时间:(转换成的是本地时区的时间)如果参数未提供,则以当前时间为准
 8 #time.struct_time(tm_year=2018, tm_mon=5, tm_mday=24, tm_hour=21, tm_min=9, tm_sec=32, tm_wday=3, tm_yday=144, tm_isdst=0)
 9 
10 print(time.mktime(time.localtime()))#将一个结构化的时间转化为时间戳:1527167372.0
11 
12 print(time.strftime("%Y-%m-%d %X", time.localtime()))#2018-05-24 21:18:02
13 # strftime(format[, t]) : 把一个代表时间的元组或者结构化的时间(如由time.localtime()和 time.gmtime()返回)转化为格式化的时间字符串。
14 # 如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。
15 
16 print(time.strptime(2018-05-24 21:21:00, %Y-%m-%d %X))  #把一个格式化时间字符串转化为结构化的时间。实际上它和strftime()是逆操作。
17 #time.struct_time(tm_year=2018, tm_mon=5, tm_mday=24, tm_hour=21, tm_min=21, tm_sec=0, tm_wday=3, tm_yday=144, tm_isdst=-1)
18 #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
19 
20 print(time.asctime())#Thu May 24 21:21:01  2018
21 # 把一个表示时间的元组或者struct_time表示为这种形式:‘Thu May 24 21:21:01  2018‘,如果没有参数,将会将time.localtime()作为参数传入。
22 
23 print(time.ctime())  # Thu May 24 21:21:01  2018
24 print(time.ctime(time.time()))  # Thu May 24 21:21:01  2018
25 # 把一个时间戳转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。
26 # 它的作用相当于time.asctime(time.localtime(secs))。
View Code

datetime模块 

技术分享图片
 1 #时间加减
 2 import datetime,time
 3 
 4 print(datetime.datetime.now()) #返回 2018-05-24 21:39:23.444828
 5 print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2018-05-24
 6 print(datetime.datetime.now() )
 7 print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
 8 print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
 9 print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
10 print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
11 
12 c_time  = datetime.datetime.now()    #2018-05-24 21:39:23.445329
13 print(c_time.replace(minute=3,hour=2)) #时间替换  2018-05-24 02:03:23.445329
View Code

2、random模块

技术分享图片
 1 import random
 2 
 3 print(random.random())#(0,1) 大于0且小于1之间的小数 :0.39322977107276613
 4 print(random.randint(1,4))  #[1,4]    大于等于1且小于等于4之间的整数
 5 print(random.randrange(1,4)) #[1,4)    大于等于1且小于4之间的整数
 6 print(random.choice([1,aa,[4,5]]))#1或者aa或者[4,5]
 7 print(random.sample([1,aa,[4,5]],2))#列表元素任意2个组合
 8 print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716
 9 item=[2,4,6,7,9]
10 random.shuffle(item) #打乱item的顺序,相当于"洗牌"
11 print(item)
View Code 
技术分享图片
 1 import random
 2 checkcode = ‘‘
 3 for i in range(4):
 4     current = random.randrange(0,4)
 5     if current != i:
 6         temp = chr(random.randint(65,90))
 7     else:
 8         temp = random.randint(0,9)
 9     checkcode += str(temp)
10 print(checkcode)
生成随机验证码

3、os模块

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

4、sys模块

技术分享图片
1 import sys
2 print(sys.argv)          #命令行参数List,第一个元素是程序本身路径
3 # sys.exit(0)            #退出程序,正常退出时exit(0)
4 print(sys.version)        #获取Python解释程序的版本信息
5 print(sys.path)           #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 print(sys.platform )      #返回操作系统平台名称
7 sys.stdout.write(please:)
8 val = sys.stdin.readline()[:-1]
View Code

5、shutil模块

高级的 文件、文件夹、压缩包 处理模块

技术分享图片
 1 import shutil
 2 
 3 shutil.copyfileobj(fsrc, fdst[, length]) # 将文件内容拷贝到另一个文件中
 4 shutil.copyfileobj(open(old.xml,r), open(new.xml, w))
 5 
 6 shutil.copyfile(src, dst)# 拷贝文件
 7 shutil.copyfile(f1.log, f2.log) #目标文件无需存在
 8 
 9 shutil.copymode(src, dst)# 仅拷贝权限。内容、组、用户均不变#
10 shutil.copymode(f1.log, f2.log) #目标文件必须存在
11 
12 shutil.copystat(src, dst)# 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
13 shutil.copystat(f1.log, f2.log) #目标文件必须存在
14 
15 shutil.copy(src, dst)# 拷贝文件和权限
16 shutil.copy(f1.log, f2.log)
17 
18 shutil.copy2(src, dst)# 拷贝文件和状态信息
19 shutil.copy2(f1.log, f2.log)
20 
21 shutil.ignore_patterns(*patterns)
22 shutil.copytree(src, dst, symlinks=False, ignore=None)
23 # 递归的去拷贝文件夹
24 shutil.copytree(folder1, folder2, ignore=shutil.ignore_patterns(*.pyc, tmp*)) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
25 
26 shutil.rmtree(path[, ignore_errors[, onerror]])# 递归的去删除文件
27 shutil.rmtree(folder1)
28 
29 shutil.move(src, dst)# 递归的去移动文件,它类似mv命令,其实就是重命名。
30 shutil.move(folder1, folder3)
31 
32 
33 
34 shutil.make_archive(base_name, format,...)
35 ‘‘‘
36 创建压缩包并返回文件路径,例如:zip、tar
37 创建压缩包并返回文件路径,例如:zip、tar
38 base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
39 如 data_bak                       =>保存至当前路径
40 如:/tmp/data_bak =>保存至/tmp/
41 format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
42 root_dir: 要压缩的文件夹路径(默认当前目录)
43 owner: 用户,默认当前用户
44 group: 组,默认当前组
45 logger: 用于记录日志,通常是logging.Logger对象
46 ‘‘‘
47 import shutil
48 ret = shutil.make_archive("data_bak", gztar, root_dir=/data)  #将 /data 下的文件打包放置当前程序目录
49 rec = shutil.make_archive("/tmp/data_bak", gztar, root_dir=/data) #将 /data下的文件打包放置 /tmp/目录
50 # shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的
View Code

6、json&pickle模块

eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

技术分享图片
1 import json
2 x="[null,true,false,1]"
3 print(eval(x)) #报错,无法解析null类型,而json就可以
4 print(json.loads(x))
View Code

一个软件/程序的执行就是在处理一系列状态的变化,在编程语言中,‘状态‘会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

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

反序列化:反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

用处:1、持久保存状态;2、跨平台数据交互

python用于序列化的两个模块:

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

pickle:用于python特有的类型 和 python的数据类型间进行转换

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

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

技术分享图片
 1 import json
 2 data_obj = {name:zz,age:13,sex:M}
 3 """
 4 dumps:序列化一个对象
 5 sort_keys:根据key排序
 6 indent:以4个空格缩进,输出阅读友好型
 7 ensure_ascii: 可以序列化非ascii码(中文等)
 8 """
 9 s_dumps = json.dumps(data_obj, sort_keys=True, indent=4, ensure_ascii=False)
10 print(s_dumps)
11 # ---------------------------------------------------分割线------------------------------------------------------------
12 """
13 dump:将一个对象序列化存入文件
14 dump()的第一个参数是要序列化的对象,第二个参数是打开的文件句柄
15 注意打开文件时加上以UTF-8编码打开
16 * 运行此文件之后在统计目录下会有一个data.json文件,打开之后就可以看到json类型的文件应该是怎样定义的
17 """
18 with open("data.json", "w", encoding="UTF-8") as f_dump:
19     s_dump = json.dump(data_obj, f_dump, ensure_ascii=False)
20 print(s_dump)
21 # ---------------------------------------------------分割线------------------------------------------------------------
22 """
23 load:从一个打开的文件句柄加载数据
24 注意打开文件的编码
25 """
26 with open("data.json", "r", encoding="UTF-8") as f_load:
27     r_load = json.load(f_load)
28 print(r_load)
29 # ---------------------------------------------------分割线------------------------------------------------------------
30 """
31 loads: 从一个对象加载数据
32 """
33 r_loads = json.loads(s_dumps)
34 print(r_loads)
35 # ---------------------------------------------------分割线------------------------------------------------------------
36 # 说明
37 # dct="{‘1‘:111}"#json 不认单引号
38 # dct=str({"1":111})#报错,因为生成的数据还是单引号:{‘one‘: 1}
39 dct={"1":"111"}
40 print(json.loads(dct))
41 # 无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
json
技术分享图片
 1 import pickle
 2 dic={name:zz,age:13,sex:M}
 3 print(type(dic))#<class ‘dict‘>
 4 j=pickle.dumps(dic)
 5 print(type(j))#<class ‘bytes‘>
 6 
 7 f=open(dic_pickle,wb)#注意是w是写入str,wb是写入bytes,j是‘bytes‘
 8 f.write(j)  #-------------------等价于pickle.dump(dic,f)
 9 f.close()
10 
11 #-------------------------反序列化
12 f=open(dic_pickle,rb)
13 data=pickle.loads(f.read())#  等价于data=pickle.load(f)
14 print(data[age])
15 """
16 Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python
17 可能不同版本的Python彼此都不兼容
18 因此,只用Pickle保存那些不重要的数据
19 即使不能成功地反序列化也没关系。
20 """
pickle

7、shelve 模块

 shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型;shelve模块是将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

技术分享图片
1 import shelve
2 
3 f=shelve.open(rsheve.txt)
4 f[stu1_info]={name:aa,age:18,hobby:[p,s,d]}
5 f[stu2_info]={name:zz,age:13}
6 f[school_info]={web:http://www.pypy.com,city:beijing}
7 
8 print(f[stu1_info][hobby])
9 f.close()
View Code

8、xml模块

xml是实现不同语言或程序之间进行数据交换的协议,很多传统公司如金融行业的很多系统的接口还主要是xml。

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>
View Code
技术分享图片
 1 import xml.etree.ElementTree as ET
 2 
 3 tree = ET.parse("xmltest.xml")
 4 root = tree.getroot()
 5 print(root.tag)
 6 
 7 #遍历xml文档
 8 for country in root:
 9     print(========>,country.tag,country.attrib,country.attrib[name])
10     for i in country:
11         print(i.tag,i.attrib,i.text)
12 #只遍历year 节点
13 for node in root.iter(year):
14     print(node.tag,node.text)
15 #---------------------------------------
16 #修改
17 for node in root.iter(year):
18     new_year=int(node.text)+1
19     node.text=str(new_year)
20     node.set(updated,yes)
21     node.set(version,1.0)
22 tree.write(test.xml)
23 
24 #删除node
25 for country in root.findall(country):
26    rank = int(country.find(rank).text)
27    if rank > 50:
28      root.remove(country)
29 tree.write(output.xml)
30 
31 #在country内添加(append)节点year2
32 for country in root.findall(country):
33     for year in country.findall(year):
34         if int(year.text) > 2000:
35             year2=ET.Element(year2)
36             year2.text=new
37             year2.attrib={update:yes}
38             country.append(year2) #往country节点下添加子节点
39 tree.write(a.xml)
xml增删改查
技术分享图片
 1 import xml.etree.ElementTree as ET 
 2 new_xml = ET.Element("namelist")
 3 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
 4 age = ET.SubElement(name,"age",attrib={"checked":"no"})
 5 sex = ET.SubElement(name,"sex")
 6 sex.text = 33
 7 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
 8 age = ET.SubElement(name2,"age")
 9 age.text = 19
10  
11 et = ET.ElementTree(new_xml) #生成文档对象
12 et.write("test.xml", encoding="utf-8",xml_declaration=True)
13 
14 ET.dump(new_xml) #打印生成的格式
创建xml

9、configparser模块

用于生成和修改常见配置文档

技术分享图片
 1 import configparser
 2 config = configparser.ConfigParser()
 3 config["DEFAULT"] = {ServerAliveInterval: 45,
 4                       Compression: yes,
 5                      CompressionLevel: 9}
 6 config[bitbucket.org] = {}
 7 config[bitbucket.org][User] = hg
 8 config[topsecret.server.com] = {}
 9 topsecret = config[topsecret.server.com]
10 topsecret[Host Port] = 50022     # mutates the parser
11 topsecret[ForwardX11] = no  # same here
12 config[DEFAULT][ForwardX11] = yes
13 with open(example.ini, w) as configfile:
14    config.write(configfile)
15    
创建
技术分享图片
 1 import configparser
 2 
 3 config=configparser.ConfigParser()
 4 config.read(example.ini)
 5 
 6 #查看所有的标题
 7 res=config.sections() #[‘bitbucket.org‘, ‘topsecret.server.com‘]
 8 print(res)
 9 
10 #查看标题bitbucket.org下所有key=value的key
11 options=config.options(bitbucket.org)
12 print(options) #[‘user‘, ‘compressionlevel‘, ‘serveraliveinterval‘, ‘compression‘, ‘forwardx11‘]
13 
14 #查看标题bitbucket.org下所有key=value的(key,value)格式
15 item_list=config.items(bitbucket.org)
16 print(item_list) #[(‘compressionlevel‘, ‘9‘), (‘serveraliveinterval‘, ‘45‘), (‘compression‘, ‘yes‘), (‘forwardx11‘, ‘yes‘), (‘user‘, ‘hg‘)]
17 
18 #查看标题bitbucket.org下user的值=>字符串格式
19 val=config.get(bitbucket.org,user)
20 print(val) #hg
21 
22 #查看标题bitbucket.org下compressionlevel的值=>整数格式
23 val1=config.getint(bitbucket.org,compressionlevel)
24 print(val1) #9
25 
26 #查看标题bitbucket.org下compression的值=>布尔值格式
27 val2=config.getboolean(bitbucket.org,compression)
28 print(val2) #True
29 
30 
31 #删除整个标题section2
32 config.remove_section(topsecret.server.com)
33 
34 #删除标题bitbucket.org下的user
35 config.remove_option(bitbucket.org,user)
36 
37 #判断是否存在某个标题
38 print(config.has_section(bitbucket.org))
39 
40 #判断标题bitbucket.org下是否有forwardx11
41 print(config.has_option(bitbucket.org,forwardx11))
42 
43 #添加一个标题
44 config.add_section(egon)
45 
46 #在标题egon下添加name=egon,age=18的配置
47 config.set(egon,name,egon)
48 config.set(egon,age,18) #必须是字符串
49 
50 #最后将修改的内容写入文件,完成最终的修改
51 config.write(open(a.ini,w))
configparser增删改查

 10、hashlib模块

 hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值

特点:

a、 只要传入的内容一样,得到的hash值必然一样=====>用于明文传输密码文件完整性校验

b、不能由hash值返解成内容=====>把密码做成hash值,用于网络传输

c、只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的

技术分享图片
 1 import hashlib
 2 
 3 m=hashlib.md5()# m=hashlib.sha256()
 4 
 5 m.update(hello.encode(utf8))
 6 print(m.hexdigest())  #5d41402abc4b2a76b9719d911017c592
 7 
 8 m.update(zz.encode(utf8))
 9 
10 print(m.hexdigest())  #bcb13ffa8bb7b827b0ba99fce02ab86d
11 
12 m2=hashlib.md5()
13 m2.update(hellozz.encode(utf8))
14 print(m2.hexdigest()) #bcb13ffa8bb7b827b0ba99fce02ab86d
15 
16 ‘‘‘
17 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
18 但是update多次为校验大文件提供了可能。
19 ‘‘‘
View Code

对加密算法中添加自定义key再来做加密:

技术分享图片
1 import hashlib
2 hash = hashlib.md5(abcd.encode(utf8))
3 hash.update(zz.encode(utf8))
4 print (hash.hexdigest())#363110069610b4595ebb1596dd172517
View Code
技术分享图片
 1 #要想保证hmac最终结果一致,必须保证:
 2 #1:hmac.new括号内指定的初始key一样
 3 #2:无论update多少次,校验的内容累加到一起是一样的内容
 4 import hmac
 5 h1=hmac.new(bzz)
 6 h1.update(ba)
 7 h1.update(bb)
 8 print(h1.hexdigest())
 9 
10 h2=hmac.new(bzz)
11 h2.update(bab)
12 print(h2.hexdigest())
13 
14 h3=hmac.new(bzzab)
15 print(h3.hexdigest())
16 
17 ‘‘‘
18 60bf58ffc6dfe4e09579740e0b4c58b6
19 60bf58ffc6dfe4e09579740e0b4c58b6
20 c56b1689c5433fbee2cbab77a253ed29
21 ‘‘‘
hmac

 11、re模块

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

模式 描述
\w 匹配字母数字及下划线
\W 匹配非字母数字及下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f].
\S 匹配任意非空字符
\n 匹配一个换行符
\t 匹配一个制表符
\d 匹配任意数字,等价于 [0-9]
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束
^ 匹配字符串的开头
$ 匹配字符串的末尾
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
[...] 用来表示一组字符,单独列出:[amk] 匹配 ‘a‘,‘m‘或‘k‘
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符
* 匹配0个或多个的表达式
+ 匹配1个或多个的表达式
? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
{n} 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o
{n,} 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"
{n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b 匹配a或b
() 分组:匹配括号内的表达式,也表示一个组
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域
(?: re) 类似 (...), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释
(?= re) 前向肯定界定符。
(?! re) 前向否定界定符
(?> re) 匹配的独立模式,省去回溯

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

   

  

 

 

技术分享图片
  1 #正则匹配
  2 import re
  3 #\w:匹配字母数字及下划线与;
  4 #\W:匹配非字母数字及下划线
  5 print(re.findall(\w,runoob 123 google 456)) #[‘r‘, ‘u‘, ‘n‘, ‘o‘, ‘o‘, ‘b‘, ‘1‘, ‘2‘, ‘3‘, ‘g‘, ‘o‘, ‘o‘, ‘g‘, ‘l‘, ‘e‘, ‘4‘, ‘5‘, ‘6‘]
  6 print(re.findall(\W,runoob 123 google 456)) #[‘ ‘, ‘ ‘, ‘ ‘]
  7 
  8 #\s:匹配任意空白字符,等价于 [\t\n\r\f]
  9 #\S:匹配任意非空字符
 10 print(re.findall(\s,runoob 123 google 456)) #[‘ ‘, ‘ ‘, ‘ ‘]
 11 print(re.findall(\s,runoob \n 123 \t google)) #[‘ ‘, ‘\n‘, ‘ ‘, ‘ ‘, ‘\t‘, ‘ ‘]  #\n \t都是空,都可以被\s匹配
 12 print(re.findall(\S,runoob 123 google 456)) #[‘r‘, ‘u‘, ‘n‘, ‘o‘, ‘o‘, ‘b‘, ‘1‘, ‘2‘, ‘3‘, ‘g‘, ‘o‘, ‘o‘, ‘g‘, ‘l‘, ‘e‘, ‘4‘, ‘5‘, ‘6‘]
 13 
 14 #\n:匹配一个换行符
 15 #\t:匹配一个制表符
 16 print(re.findall(r\n,hello egon \n123)) #[‘\n‘]
 17 print(re.findall(r\t,hello egon\t123)) #[‘\t‘]
 18 
 19 #\d:匹配任意数字,等价于 [0-9]
 20 #\D:匹配任意非数字
 21 print(re.findall(\d,hello egon 123)) #[‘1‘, ‘2‘, ‘3‘]
 22 print(re.findall(\D,hello \n egon 123)) #[‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘ ‘, ‘\n‘, ‘ ‘, ‘e‘, ‘g‘, ‘o‘, ‘n‘, ‘ ‘]
 23 
 24 #\A:匹配字符串开始
 25 #\Z:匹配字符串结束
 26 print(re.findall(\Ahe,hello egon 123)) #[‘he‘],\A==>^
 27 print(re.findall(123\Z,hello egon 123)) #[‘he‘],\Z==>$
 28 
 29 #^:匹配字符串的开头
 30 #$:匹配字符串的末尾
 31 print(re.findall(^h,hello egon 123)) #[‘h‘]
 32 print(re.findall(3$,hello egon 123)) #[‘3‘]
 33 
 34 # 重复匹配:
 35 # .:匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
 36 print(re.findall(a.b,a1b)) #[‘a1b‘]
 37 print(re.findall(a.b,a1b a*b a b aaab)) #[‘a1b‘, ‘a*b‘, ‘a b‘, ‘aab‘]
 38 print(re.findall(a.b,a\nb)) #[]
 39 print(re.findall(a.b,a\nb,re.S)) #[‘a\nb‘]
 40 print(re.findall(a.b,a\nb,re.DOTALL)) #[‘a\nb‘]同上一条意思一样
 41 
 42 
 43 # *:匹配0个或多个的表达式
 44 print(re.findall(ab*,bbbbbbb)) #[](b可以是0个或多个,但第一个必须是a)
 45 print(re.findall(ab*,acc)) #[‘a‘]
 46 print(re.findall(ab*,abbbb)) #[‘abbbb‘]
 47 
 48 #+:匹配1个或多个的表达式
 49 print(re.findall(ab+,a)) #[]
 50 print(re.findall(ab+,abbb)) #[‘abbb‘]
 51 
 52 #?:匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
 53 print(re.findall(ab?,a)) #[‘a‘]
 54 print(re.findall(ab?,abbb)) #[‘ab‘]
 55 
 56 #匹配所有包含小数在内的数字
 57 print(re.findall(\d+\.?\d*,"asdfasdf123as1.13dfa12adsf1asdf3")) #[‘123‘, ‘1.13‘, ‘12‘, ‘1‘, ‘3‘]
 58 
 59 #.*默认为贪婪匹配
 60 print(re.findall(a.*b,a1b22222222b)) #[‘a1b22222222b‘]
 61 #.*?为非贪婪匹配:推荐使用
 62 print(re.findall(a.*?b,a1b22222222b)) #[‘a1b‘]
 63 
 64 #{n,m}:匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
 65 print(re.findall(ab{2},abbb)) #[‘abb‘]
 66 print(re.findall(ab{1,3},abbb)) #[‘abbb‘]
 67 print(re.findall(ab{1,},abbb)) #‘ab{1,}‘ ===> ‘ab+‘
 68 print(re.findall(ab{0,},abbb)) #‘ab{0,}‘ ===> ‘ab*‘
 69 
 70 #[...]:用来表示一组字符,单独列出:[amk] 匹配 ‘a‘,‘m‘或‘k‘
 71 #[^...]:不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符
 72 print(re.findall(a[1*-]b,a1b a*b a-b)) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾:[‘a1b‘, ‘a*b‘, ‘a-b‘]
 73 print(re.findall(a[^1*-]b,a1b a*b a-b a=b)) #[‘a=b‘]
 74 print(re.findall(a[0-9]b,a1b a*b a-b a=b)) #[][‘a1b‘]
 75 print(re.findall(a[a-z]b,a1b a*b a-b a=b aeb)) #[‘aeb‘]
 76 print(re.findall(a[a-zA-Z]b,a1b a*b a-b a=b aeb aEb)) #[‘aeb‘, ‘aEb‘]
 77 
 78 #|:匹配a或b
 79 print(re.findall(compan(?:y|ies),Too many companies have gone bankrupt, and the next one is my company)) #[‘companies‘, ‘company‘]
 80 
 81 #():分组匹配括号内的表达式,也表示一个组
 82 print(re.findall(ab+,ababab123)) #[‘ab‘, ‘ab‘, ‘ab‘]
 83 print(re.findall((ab)+123,ababab123)) #[‘ab‘],匹配到末尾的ab123中的ab
 84 print(re.findall((?:ab)+123,ababab123)) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
 85 print(re.findall(href="(.*?)",<a href="http://www.baidu.com">点击</a>))#[‘http://www.baidu.com‘]
 86 print(re.findall(href="(?:.*?)",<a href="http://www.baidu.com">点击</a>))#[‘href="http://www.baidu.com"‘]
 87 
 88 
 89 
 90 ‘‘‘
 91 反斜杠的困扰:与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。
 92 假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\";
 93 前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
 94 Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。
 95 同样,匹配一个数字的"\\d"可以写成r"\d"。
 96 有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
 97 ‘‘‘
 98 # print(re.findall(‘a\\c‘,‘a\c‘)) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常
 99 print(re.findall(ra\\c,a\c)) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
100 print(re.findall(a\\\\c,a\c)) #同上面的意思一样,和上面的结果一样都是[‘a\\c‘]
匹配模式 
技术分享图片
  1 ‘‘‘
  2 最常用的匹配语法:
  3 re.findall 把所有匹配到的字符放到列表中以元素返回
  4 re.search 匹配包含
  5 re.match 从头开始匹配
  6 re.split 以匹配到的字符当做列表分隔符
  7 re.sub   匹配字符并替换
  8 ‘‘‘
  9 import re
 10 print(re.findall(o,runoob 123 google 456) )   #[‘o‘, ‘o‘, ‘o‘, ‘o‘],返回所有满足匹配条件的结果,放在列表里
 11 print(re.search(o,runoob 123 google 456).group()) #o,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
 12 print(re.match(o,runoob 123 google 456))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
 13 print(re.split([ab],abcd))     #[‘‘, ‘‘, ‘cd‘],先按‘a‘分割得到‘‘和‘bcd‘,再对‘‘和‘bcd‘分别按‘b‘分割
 14 print(===>,re.sub(o,A,runoob 123 google 456)) #===> runAAb 123 gAAgle 456,不指定n,默认替换所有
 15 print(===>,re.sub(o,A,runoob 123 google 456,1)) #===> runAob 123 google 456
 16 print(===>,re.sub(o,A,runoob 123 google 456,2)) #===> runAAb 123 google 456
 17 print(===>,re.sub(^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$,r\5\2\3\4\1,runoob 123 google)) #===> google 123 runoob
 18 print(===>,re.subn(o,A,runoob 123 google 456)) #===> (‘runAAb 123 gAAgle 456‘, 4),结果带有总共替换的个数
 19 obj=re.compile(\d{2})
 20 print(obj)
 21 print(obj.search(abc123eeee).group()) #12
 22 print(obj.findall(abc123eeee)) #[‘12‘],重用了obj
 23 print(re.findall(r-?\d+\.?\d*,"1-12*(60+(-40.35/5)-(-4*3))")) #找出所有数字[‘1‘, ‘-12‘, ‘60‘, ‘-40.35‘, ‘5‘, ‘-4‘, ‘3‘]
 24 #使用|,先匹配的先生效,|左边是匹配小数,而findall最终结果是查看分组,所以即使匹配成功小数也不会存入结果
 25 #而不是小数时,就去匹配(-?\d+)
 26 print(re.findall("-?\d+\.\d*|(-?\d+)","1-12*(60+(-40.35/5)-(-4*3))")) #找出所有整数[‘1‘, ‘-12‘, ‘60‘, ‘‘, ‘5‘, ‘-4‘, ‘3‘]
 27 #为何同样的表达式search与findall却有不同结果:
 28 print(re.search(\(([\+\-\*\/]*\d+\.?\d*)+\),"1-12*(60+(-40.35/5)-(-4*3))").group()) #(-40.35/5)
 29 print(re.findall(\(([\+\-\*\/]*\d+\.?\d*)+\),"1-12*(60+(-40.35/5)-(-4*3))")) #[‘/5‘, ‘*3‘]
 30 #看这个例子:(\d)+相当于(\d)(\d)(\d)(\d)...,是一系列分组
 31 print(re.search((\d)+,123).group()) #group的作用是将所有组拼接到一起显示出来
 32 print(re.findall((\d)+,123)) #findall结果是组内的结果,且是最后一个组的结果
 33 
 34 s=‘‘‘
 35 http://www.baidu.com
 36 egon@oldboyedu.com
 37 你好
 38 010-3141
 39 ‘‘‘
 40 #最常规匹配
 41 content=Hello 123 456 World_This is a Regex Demo
 42 res=re.match(Hello\s\d\d\d\s\d{3}\s\w{10}.*Demo,content)
 43 print(res)
 44 print(res.group())
 45 print(res.span())
 46 #泛匹配
 47 res=re.match(^Hello.*Demo,content)
 48 print(res.group())
 49 #匹配目标,获得指定数据
 50 res=re.match(^Hello\s(\d+)\s(\d+)\s.*Demo,content)
 51 print(res.group()) #取所有匹配的内容
 52 print(res.group(1)) #取匹配的第一个括号内的内容
 53 print(res.group(2)) #去陪陪的第二个括号内的内容
 54 #贪婪匹配:.*代表匹配尽可能多的字符
 55 res=re.match(^He.*(\d+).*Demo$,content)
 56 print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字
 57 #非贪婪匹配:?匹配尽可能少的字符
 58 res=re.match(^He.*?(\d+).*Demo$,content)
 59 print(res.group(1)) #123
 60 #匹配模式:.不能匹配换行符
 61 content=‘‘‘Hello 123456 World_This
 62 is a Regex Demo
 63 ‘‘‘
 64 res=re.match(He.*?(\d+).*?Demo$,content)
 65 print(res) #输出None
 66 res=re.match(He.*?(\d+).*?Demo$,content,re.S) #re.S让.可以匹配换行符
 67 print(res)
 68 print(res.group(1))
 69 #转义:\
 70 content=price is $5.00
 71 res=re.match(price is $5.00,content)
 72 print(res) #None
 73 res=re.match(price is \$5\.00,content)
 74 print(res) #<_sre.SRE_Match object; span=(0, 14), match=‘price is $5.00‘>
 75 ‘‘‘
 76 尽量精简,详细的如下:
 77 尽量使用泛匹配模式.*
 78 尽量使用非贪婪模式:.*?
 79 使用括号得到匹配目标:用group(n)去取得结果
 80 有换行符就用re.S:修改模式
 81 ‘‘‘
 82 #re.search:会扫描整个字符串,不会从头开始,找到第一个匹配的结果就会返回
 83 content=Extra strings Hello 123 456 World_This is a Regex Demo Extra strings
 84 res=re.match(Hello.*?(\d+).*?Demo,content)
 85 print(res) #输出结果为None
 86 res=re.search(Hello.*?(\d+).*?Demo,content)
 87 print(res.group(1)) #输出结果为123
 88 #re.sub:字符串替换
 89 content=Extra strings Hello 123 456 World_This is a Regex Demo Extra strings
 90 content=re.sub(\d+,‘‘,content)
 91 print(content)
 92 #用\1取得第一个括号的内容
 93 #用法:将123与456换位置
 94 content=Extra strings Hello 123 456 World_This is a Regex Demo Extra strings
 95 content=re.sub((Extra.*?)(\d+)(\s)(\d+)(.*?strings),r\1\4\3\2\5,content)
 96 print(content)
 97 content=re.sub((\d+)(\s)(\d+),r\3\2\1,content)
 98 print(content)
 99 res=re.search(Extra.*?(\d+).*strings,content)
100 print(res.group(1))
匹配语法

 12、suprocess模块

subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn*、os.popen*、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

call:执行命令,返回状态码

ret = subprocess.call(["ls", "-l"], shell=False)

ret = subprocess.call("ls -l", shell=True)

check_call:执行命令,如果执行状态码是 0 ,则返回0,否则抛异常 

subprocess.check_call(["ls", "-l"])

subprocess.check_call("exit 1", shell=True)

check_output:执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常

subprocess.check_output(["echo", "Hello World!"])

subprocess.check_output("exit 1", shell=True)

subprocess.Popen(...):用于执行复杂的系统命令 

参数:

args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

技术分享图片
1 import subprocess
2 res1=subprocess.Popen(rdir D:\zz\aa\t1,shell=True,stdout=subprocess.PIPE)
3 res=subprocess.Popen(findstr test*,shell=True,stdin=res1.stdout,
4                  stdout=subprocess.PIPE)
5 print(res.stdout.read())
View Code

13、logging模块

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() , critical() 5个级别

技术分享图片
1 CRITICAL = 50 #FATAL = CRITICAL
2 ERROR = 40
3 WARNING = 30 #WARN = WARNING
4 INFO = 20
5 DEBUG = 10
6 NOTSET = 0 #不设置
View Code
技术分享图片
 1 import logging
 2 
 3 logging.debug(调试debug)
 4 logging.info(消息info)
 5 logging.warning(警告warn)
 6 logging.error(错误error)
 7 logging.critical(严重critical)
 8 
 9 ‘‘‘
10 WARNING:root:警告warn
11 ERROR:root:错误error
12 CRITICAL:root:严重critical
13 ‘‘‘
简单用法

为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

技术分享图片
 1 ‘‘‘
 2 可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
 3 filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
 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 format参数中可能用到的格式化串:
10 %(name)s:Logger的名字,并非用户名,详细查看
11 %(levelno)s:数字形式的日志级别
12 %(levelname)s:文本形式的日志级别
13 %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
14 %(filename)s:调用日志输出函数的模块的文件名
15 %(module)s:调用日志输出函数的模块名
16 %(funcName)s:调用日志输出函数的函数名
17 %(lineno)d:调用日志输出函数的语句所在的代码行
18 %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
19 %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
20 %(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
21 %(thread)d:线程ID。可能没有
22 %(threadName)s:线程名。可能没有
23 %(process)d:进程ID。可能没有
24 %(message)s:用户输出的消息
25 ‘‘‘
26 import logging
27 logging.basicConfig(filename=example.log,
28                     format=%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
29                     datefmt=%Y-%m-%d %H:%M:%S %p,
30                     level=10)
31 
32 logging.debug(debug)
33 logging.info(info)
34 logging.warning(warn)
35 logging.error(error)
36 logging.critical(critical)
37 # 输出:
38 ‘‘‘
39 2018-06-01 20:52:44 PM - root - DEBUG -log模块:  debug
40 2018-06-01 20:52:44 PM - root - INFO -log模块:  info
41 2018-06-01 20:52:44 PM - root - WARNING -log模块:  warn
42 2018-06-01 20:52:44 PM - root - ERROR -log模块:  error
43 2018-06-01 20:52:44 PM - root - CRITICAL -log模块:  critical
44 2018-06-01 20:53:01 PM - root - DEBUG -log模块:  debug
45 2018-06-01 20:53:01 PM - root - INFO -log模块:  info
46 2018-06-01 20:53:01 PM - root - WARNING -log模块:  warn
47 2018-06-01 20:53:01 PM - root - ERROR -log模块:  error
48 2018-06-01 20:53:01 PM - root - CRITICAL -log模块:  critical
49 ‘‘‘
View Code

Python+logger流示意图

技术分享图片

Python 使用logging模块记录日志涉及四个主要类:

logger:产生日志的对象,提供了应用程序可以直接使用的接口;

handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端;

filter:过滤日志的对象,提供了细度设备来决定输出哪条日志记录;

formatter:决定日志记录的最终输出格式,可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式。

技术分享图片
 1 import logging
 2 ‘‘‘
 3 logger
 4 每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
 5 LOG=logging.getLogger(”chat.gui”)
 6 而核心模块可以这样:
 7 LOG=logging.getLogger(”chat.kernel”)
 8 Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
 9 Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
10 Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
11 Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
12 ‘‘‘
13 #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
14 logger=logging.getLogger(__file__)
15 ‘‘‘
16 handler 
17 handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
18 Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
19 Handler.setFormatter():给这个handler选择一个格式
20 Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
21 
22 每个Logger可以附加多个Handler。常用的Handler:
23 1) logging.StreamHandler
24 使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
25 StreamHandler([strm])
26 其中strm参数是一个文件对象。默认是sys.stderr
27 2) logging.FileHandler
28 和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
29 FileHandler(filename[,mode])
30 filename是文件名,必须指定一个文件名。
31 mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a‘,即添加到文件末尾。
32 3) logging.handlers.RotatingFileHandler
33 这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
34 RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
35 其中filename和mode两个参数和FileHandler一样。
36 maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
37 backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
38 4) logging.handlers.TimedRotatingFileHandler
39 这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
40 TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
41 其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
42 interval是时间间隔。
43 when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
44 S 秒
45 M 分
46 H 小时
47 D 天
48 W 每星期(interval==0时代表星期一)
49 midnight 每天凌晨
50 ‘‘‘
51 #2、Handler对象:接收logger传来的日志,然后控制输出
52 h1=logging.FileHandler(t1.log) #打印到文件
53 h2=logging.FileHandler(t2.log) #打印到文件
54 h3=logging.StreamHandler() #打印到终端
55 #3、Formatter对象:日志格式
56 formmater1=logging.Formatter(%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
57                     datefmt=%Y-%m-%d %H:%M:%S %p,)
58 formmater2=logging.Formatter(%(asctime)s :  %(message)s,
59                     datefmt=%Y-%m-%d %H:%M:%S %p,)
60 formmater3=logging.Formatter(%(name)s %(message)s,)
61 #4、为Handler对象绑定格式
62 h1.setFormatter(formmater1)
63 h2.setFormatter(formmater2)
64 h3.setFormatter(formmater3)
65 #5、将Handler添加给logger并设置日志级别
66 logger.addHandler(h1)
67 logger.addHandler(h2)
68 logger.addHandler(h3)
69 logger.setLevel(10)
70 #6、测试
71 logger.debug(debug)
72 logger.info(info)
73 logger.warning(warning)
74 logger.error(error)
75 logger.critical(critical)
View Code

logger是第一级过滤,然后才能到handler,我们可以给logger和handler同时设置level,Logger是第一个根据级别过滤消息的,如果您将Logger设置为INFO,并将所有处理程序都设置为DEBUG,那么仍然不会接收处理程序上的调试消息,它们将被Logger本身拒绝。如果您将日志记录器设置为DEBUG,而所有处理程序都设置为INFO,那么您也不会收到任何调试消息,因为当日志记录器说“ok, process this”时,处理程序会拒绝它(DEBUG < INFO)。

 

python基础07

标签:日志输出   present   ec2   python基础   archive   精简   %s   存在   web   

原文地址:https://www.cnblogs.com/hy0822/p/9085046.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!