python基础07

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)

 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))。

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

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)

 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的大小

 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]

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 两个模块来进行的

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))

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

序列化:我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化。在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(r‘sheve.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()

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>

 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 ‘‘‘

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

1 import hashlib
2 hash = hashlib.md5(‘abcd‘.encode(‘utf8‘))
3 hash.update(‘zz‘.encode(‘utf8‘))
4 print (hash.hexdigest())#363110069610b4595ebb1596dd172517

 1 #要想保证hmac最终结果一致,必须保证:
 2 #1:hmac.new括号内指定的初始key一样
 3 #2:无论update多少次,校验的内容累加到一起是一样的内容
 4 import hmac
 5 h1=hmac.new(b‘zz‘)
 6 h1.update(b‘a‘)
 7 h1.update(b‘b‘)
 8 print(h1.hexdigest())
 9
10 h2=hmac.new(b‘zz‘)
11 h2.update(b‘ab‘)
12 print(h2.hexdigest())
13
14 h3=hmac.new(b‘zzab‘)
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(r‘a\\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 [email protected]
 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(r‘dir 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())

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 #不设置

 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 ‘‘‘

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‘)

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

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

时间: 2024-08-02 17:40:35

python基础07的相关文章

Python基础07 函数

Python基础07 函数 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 函数最重要的目的是方便我们重复使用相同的一段程序. 将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的语句. 函数的定义 首先,我们要定义一个函数, 以说明这个函数的功能. def square_sum(a,b): c = a**2 + b**2 return c 这个函数的功能是求两个数的平方和. 首先

Python基础07 文件对象

Python具有基本的文本文件读写功能.Python的标准库提供有更丰富的读写功能. 文本文件的读写主要通过open()所构建的文件对象来实现. 创建文件对象 我们打开一个文件,并使用一个对象来表示该文件: f = open(文件名,模式) 常用的模式有: 'r':读 'w':写 'a':追加 'r+' :r+w(可读可写,文件若不存在就报错 IOError) 'w+' : w+r(可读可写,文件若不存在就创建) 'a+' :a+r(可追加可写,文件若不存在就创建) 对应的,如果是二进制文件,就

python基础学习07(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #file与input output #文件对象 #简单说来,就是写入和读取的方式 #file(),open()2个操作都是一样的,一般推荐open() #语法 # open(name[, mode[, bufferin

Python基础学习笔记(十)日期Calendar和时间Timer

参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-date-time.html 3. http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000 时间间隔是以秒为单位的浮点函数.获取该时间的实例如下: 时间元组struct_time: 序号 属性 值 0 tm_year 2008 1 tm_mon 1 到 12 2 t

Java基础07 包(转载)

包(package)的目的就是为了更好的组织Java程序. 包的建立 包的建立非常简单.我们只用在Java程序的开始加入package就可以了.我们以Human类为例,将它放入包中: package com.vamei.society; public class Human{    /**     * constructor     */    public Human(int h){        this.height = h;        System.out.println("I'm

python基础学习09(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #什么是函数 #就是引用,创建,使用 #例子 def foo(): print '233' foo() #返回与函数类型 def foo1():#是一个过程 print 'hello world!' foo1() foo

python 基础教程 笔记 一

第一章 python 基础知识 1.1 数字和数学表达式 1.2 python 2.x 和python 3.x print的区别 1.3 python 2.x 和 python 3.x input 的区别 1.4 数学函数 1.5 input 和 raw_input 区别 第二章 列表和元组 第三章 使用字符串 1.1 数字和表达式 Python 默认的除法:整数/整数,无论是否整除都得到整数,不整除的截取小时部分 1 / 2 0 如果想要Python 执行普通的除法,可以之用浮点数来实现也可以

python基础学习(一)

一,Python介绍 1,python的出生与应用 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承. (龟叔:2005年加入谷歌至2012年,2013年加入Dropbox直到现在,依然掌握着Python发展的核心方向,被称为仁慈的独裁者). 2018年10月的TIOBE排行榜,Python已经占据第四的位置, Python崇尚优美.清

linux+jmeter+python基础+抓包拦截

LINUX 一 配置jdk 环境 *需要获取root权限,或者切换为root用户 1.windows下载好,去 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 官方网站下载jdk(linux相应版本) 2.在usr目录下创建java路径文件夹 [root bin]cd /usr mkdir java 3.将jdk-8u60-linux-x64.tar.gz放到刚才创建的文件夹下