zoukankan      html  css  js  c++  java
  • 超好用的模块

    模块介绍

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

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

    模块分为三种:

    • 自定义模块

    • 内置标准模块(又称标准库)

    • 开源模块

    导入模块:

    • import: 使客户端(导入者)以一个整体获取一个模块。

    • from:容许客户端从一个模块文件中获取特定的变量名。

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

    导入模块方法:

    复制代码
     1 语法:
     2 import module
     3 from module.xx.xx import xx     
     4 from module.xx.xx import xx as rename 
     5 from module.xx.xx import *            #一般不推荐使用
     6 
     7 
     8 示例:
     9 
    10 推荐方法一:
    11 
    12 import cal   #当前目录直接调用模块
    13 
    14 from my_module import cal     #二层目录调用模块
    15 
    16 from web1,web2,web3 import cal      #多层目录调用模块
    17 
    18 推荐方法二:
    19 from web1,web2,web3.cal import add
    20 
    21 
    22 注意:不支持的调用方式
    23 from web1.web2 import web3  #执行__init__文件,唯一不支持的调用方式
    24 print(web3.cal.add(2,6))
    复制代码

    模块路径:

    复制代码
     1 #获取路径
     2 import sys
     3 for i in sys.path:
     4     print(i)
     5 
     6 #输出结果:
     7 S:Myproject
     8 S:Python 3.5.1python35.zip
     9 S:Python 3.5.1DLLs
    10 S:Python 3.5.1lib                  #存放标准库
    11 S:Python 3.5.1
    12 S:Python 3.5.1libsite-packages    #存放第三方库,扩充库
    13  
    14 #添加路径
    15 import os
    16 pre_path = os.path.abspath('../')  #当前路径
    17 import sys
    18 sys.path.append(pre_path)   #添加环境变量,临时生效
    19  环境变量:永久生效方法:我的电脑--->系统属性--->环境变量--->Path路径中添加,以";" 分割。
    复制代码

    开源模块:

    复制代码
     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环境,导入模块检查是否安装成功                       
    复制代码

    二、包(package)的概念    

    我们先设想一下,如果不同的人编写的模块名相同怎么办?为了避免冲突,Python又引进了按目录

    来组织模块的方法,称为包(package)。

    假设,如下图,我的两个time_file.py模块名字重名了,但是这两个模块的功能都不相同,如果这两个模块都在同一级目录中,那么我在其他地方要调用这个time_file.py模块,那么这个时候就会发生冲突,在这里我们就可以通过包来组织模块,避免冲突,

    方法是:选择一个顶层包名,引入包以后,只要顶层的包名不与别人冲突,那这个包里面的模块都不会与别人冲突了。

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

    、常用模块

    接下来,我会介绍一些常用的模块,数量有限,会不定时补充。

    1.time&datetime模块

    1 时间相关的操作,时间有三种表示方式:
    2  
    3 时间戳           1970年1月1日之后的秒,即:time.time()
    4 格式化的字符串    2016-12-12 10:10,  即:time.strftime('%Y-%m-%d')
    5 结构化时间       元组                 即:time.struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)    即:time.localtime()
    import time
     
    # 1 time() :返回当前时间的时间戳
    time.time()  #1473525444.037215
     
    #----------------------------------------------------------
     
    # 2 localtime([secs])
    # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
    time.localtime() #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)
    time.localtime(1473525444.037215)
     
    #----------------------------------------------------------
     
    # 3 gmtime([secs]) 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
     
    #----------------------------------------------------------
     
    # 4 mktime(t) : 将一个struct_time转化为时间戳。
    print(time.mktime(time.localtime()))#1473525749.0
     
    #----------------------------------------------------------
     
    # 5 asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
    # 如果没有参数,将会将time.localtime()作为参数传入。
    print(time.asctime())#Sun Sep 11 00:43:43 2016
     
    #----------------------------------------------------------
     
    # 6 ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为
    # None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
    print(time.ctime())  # Sun Sep 11 00:46:38 2016
     
    print(time.ctime(time.time()))  # Sun Sep 11 00:46:38 2016
     
    # 7 strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和
    # time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个
    # 元素越界,ValueError的错误将会被抛出。
    print(time.strftime("%Y-%m-%d %X", time.localtime()))#2016-09-11 00:49:56
     
    # 8 time.strptime(string[, format])
    # 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
    print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))
     
    #time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6,
    #  tm_wday=3, tm_yday=125, tm_isdst=-1)
     
    #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
     
     
    # 9 sleep(secs)
    # 线程推迟指定的时间运行,单位为秒。
     
    # 10 clock()
    # 这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。
    # 而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行
    # 时间,即两次时间差。

    示例:

     1 import time
     2 
     3 print(time.time())       #1481556467.5820887  返回当前系统时间戳(1970年1月1日0时0分0秒开始)
     4 
     5 print(time.localtime())  #将时间戳转换为struct_time格式,返回本地时间
     6 #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=12, tm_hour=23, tm_min=27, tm_sec=47, tm_wday=0, tm_yday=347, tm_isdst=0)
     7 
     8 print(time.gmtime())     #将时间戳转换为struct_time格式
     9 #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=12, tm_hour=15, tm_min=27, tm_sec=47, tm_wday=0, tm_yday=347, tm_isdst=0)
    10 
    11 print(time.mktime(time.localtime()))  #1481556446.0  与time.localtime()功能相反,将struct_time格式转回成时间戳格式
    12 
    13 print(time.asctime())      #Mon Dec 12 23:26:24 2016
    14 
    15 print(time.ctime())        #Mon Dec 12 23:26:24 2016
    16 
    17 print(time.ctime(time.time()))    #Mon Dec 12 23:26:24 2016
    18 
    19 print(time.strftime("%Y-%m-%d %X",time.localtime()))   #2016-12-12 23:26:24
    20 
    21 print(time.strptime('2016-12-12 18:25:30','%Y-%m-%d %X'))   #将字符串格式转换成struct_time格式
    22 #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=12, tm_hour=18, tm_min=25, tm_sec=30, tm_wday=0, tm_yday=347, tm_isdst=-1)
    23 
    24 #time.sleep(3)    #sleep停顿3分钟
    View Code

          

    DirectiveMeaningNotes
    %a Locale’s abbreviated weekday name.  
    %A Locale’s full weekday name.  
    %b Locale’s abbreviated month name.  
    %B Locale’s full month name.  
    %c Locale’s appropriate date and time representation.  
    %d Day of the month as a decimal number [01,31].  
    %H Hour (24-hour clock) as a decimal number [00,23].  
    %I Hour (12-hour clock) as a decimal number [01,12].  
    %j Day of the year as a decimal number [001,366].  
    %m Month as a decimal number [01,12].  
    %M Minute as a decimal number [00,59].  
    %p Locale’s equivalent of either AM or PM. (1)
    %S Second as a decimal number [00,61]. (2)
    %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)
    %w Weekday as a decimal number [0(Sunday),6].  
    %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)
    %x Locale’s appropriate date representation.  
    %X Locale’s appropriate time representation.  
    %y Year without century as a decimal number [00,99].  
    %Y Year with century as a decimal number.  
    %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].  
    %Z Time zone name (no characters if no time zone exists).  
    %% A literal '%' character.

           

     1 #时间加减
     2 import datetime
     3 
     4 # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
     5 #print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
     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 
    13 #
    14 # c_time  = datetime.datetime.now()
    15 # print(c_time.replace(minute=3,hour=2)) #时间替换

     

    2.random模块

     1 import random
     2  
     3 print(random.random())          #用于生成一个0到1的随机符点数: 0 <= n < 1.0
     4 print(random.randint(1,2))      #用于生成一个指定范围内的整数
     5 print(random.randrange(1,10))   #从指定范围内,按指定基数递增的集合中获取一个随机数
     6 print(random.uniform(1,10))     #用于生成一个指定范围内的随机符点数
     7 print(random.choice('nick'))    #从序列中获取一个随机元素
     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)

    验证码示例:

    含有三个大写字母和一个数字的验证码

     1 code = []
     2 
     3 for i in range(3):
     4     temp = chr(random.randint(65,90))
     5     code.append(temp)
     6 num = random.randint(0,9)
     7 code.append(num)
     8 
     9 random.shuffle(code)
    10 
    11 print(str(code))

     3.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下为"
    ",Linux下为"
    "
    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: getcwd 获取当前工作目录 ,chdir("..") 改变当前脚本工作目录

    1 import os
    2 
    3 print(os.getcwd())   #获取当前工作目录
    4 os.chdir("..")       #改变当前脚本工作目录,相当于shell下cd
    5 print(os.getcwd())

    执行结果:

    1 D:pythonday13
    2 D:python

    ps2: makedirs 递归创建空目录

    1 import os
    2 
    3 os.makedirs('dirname1/dirname2')  #创建两层空目录

    ps3: removedirs  若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

    1 import os
    2 
    3 os.removedirs("dirname1/dirname2")

    ps4: listdir 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

    1 import os
    2 
    3 print(os.listdir())   #显示当前目录下所有内容

    ps5: stat 获取文件/目录信息

    stat 结构:

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

    执行结果:

    1 os.stat_result(st_mode=33206, st_ino=8162774324611606, st_dev=1753083748, st_nlink=1, st_uid=0, st_gid=0, st_size=464, st_atime=1481615313, st_mtime=1481615313, st_ctime=1481610945)

    ps6: os.system(("dir")) 显示目录和文件

    1 import os
    2 print(os.system("dir"))  #显示目录和文件

    执行结果:

    复制代码
     1  Volume in drive D is SSD
     2  Volume Serial Number is 687D-EF64
     3 
     4  Directory of D:python	est
     5 
     6 2016/12/27  15:39    <DIR>          .
     7 2016/12/27  15:39    <DIR>          ..
     8 2016/12/01  20:50               563 for.py
     9 2016/12/09  08:20            21,892 haproxy01.py
    10 2016/12/09  08:27             8,112 haproxy02.py
    11 2016/12/24  23:10                16 hello
    12 2016/12/27  15:39               258 os_module.py
    13 2016/12/23  09:53               381 s1.py
    14 2016/12/06  15:01               969 s2.py
    15 2016/12/22  10:08               149 s4.py
    16 2016/12/24  23:16               699 s5.py
    17 2016/12/27  14:59               348 s6.py
    18 2016/12/27  15:33               308 sys_module.py
    19 2016/12/09  13:14             2,631 test.txt
    20               12 File(s)         36,326 bytes
    21                2 Dir(s)  639,014,264,832 bytes free
    复制代码

    ps7: os.path.split 将文件分割成目录和文件名

    1 import os
    2 print(os.path.split(r"C:UsersAdministrator脱产三期day22sss.py"))   #将path分割成目录和文件名

    执行结果:

    1 ('C:\Users\Administrator\脱产三期\day22', 'sss.py')

    ps8: os.path.dirname  返回path的目录,加了r转义

    1 import os
    2 print(os.path.dirname(r"C:UsersAdministrator脱产三期day22sss.py"))  #返回path的目录。其实就是os.path.split(path)的第一个元素

    执行结果:

    1 C:UsersAdministrator脱产三期day22

    ps9: 文件路径的综合应用

    复制代码
     1 print(__file__)  #获取当前文件路径的文件名
     2 
     3 结果:D:/python/test/os_module.py
     4 
     5 
     6 print(os.path.dirname(__file__))  #返回上一层目录
     7 
     8 结果:D:/python/test
     9 
    10 
    11 print(os.path.abspath(__file__)) #返回他的绝对路径
    12 
    13 结果:D:python	estos_module.py
    14 
    15 
    16 print(os.path.split(os.path.abspath(__file__)))  #将path分割成目录和文件名
    17 
    18 结果:('D:\python\test', 'os_module.py')
    19 
    20 print(os.path.dirname(os.path.abspath(__file__)))  #返回当前文件的上一层目录
    21 
    22 结果:D:python	est
    23 
    24 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) #返回上二层的目录
    25 
    26 结果:D:python
    复制代码

    ps10: ps.path.hasename 返回path最后的文件名

    1 import os
    2 print(os.path.basename(r"C:UsersAdministrator脱产三期day22sss.py")) #返回path最后的文件名。

    执行结果:

    1 sss.py

    ps11: os.path.join 路径拼接

    ps1:

    1 import os
    2 a="D:pythonday13"
    3 b="pickle_s1.py"
    4 os.path.join(a,b)#  路径拼接

    执行结果:

    1 C:Python3.5python.exe D:/python/day13/os_test.py

    ps2: os.path.join 路径和文件名拼接

    1 print(os.path.join("d:\"))
    2 print(os.path.join("d:\","www","baidu","test.py"))

    执行结果:

    1 d:wwwaidu	est.py

    ps3: estb123.txt  os.path.join拼接出这个路径

    1 print(os.path.join(os.path.dirname(os.path.abspath(__file__)),"bb","123.txt"))

    执行结果:

    1 D:python	estb123.txt  #拼接出来的结果

    4.shelve模块

    shelve模块只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

    ps1:

    复制代码
    1 #添加键值对到文件中,会生成三个文件,并写入字典内容
    2 
    3 import shelve
    4 
    5 f = shelve.open(r'shelve1')  # 目的:将一个字典放入文本 f={}
    6 f['stu1_info']={'name':'alex','age':'18'}
    7 f['stu2_info']={'name':'alvin','age':'20'}
    8 f['school_info']={'website':'oldboyedu.com','city':'beijing'}
    9 f.close()
    复制代码

    执行结果:

    会生成三个文件:shelvel.dat,shelve1.dir,shelve1.bak,其中shelvel.bak中内容如下:

    1 'stu1_info', (0, 49)           #生成只有计算机能识别的语言
    2 'stu2_info', (512, 50)
    3 'school_info', (1024, 67)

    ps2:取出age的值

    1 import shelve
    2 
    3 f = shelve.open(r'shelve1')
    4 print(f.get('stu1_info')['age'])  #取出age的值
    5 print(f.get('stu2_info')['age'])

    执行结果:

    1 18
    2 20

    5.xml模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用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>
    24 
    25 xml数据
    复制代码

    xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

    复制代码
     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 child in root:
     9     print(child.tag, child.attrib)
    10     for i in child:
    11         print(i.tag,i.text)
    12  
    13 #只遍历year 节点
    14 for node in root.iter('year'):
    15     print(node.tag,node.text)

    #执行结果:
    year 2008
    year 2011
            year 2011 16 #--------------------------------------- 17 18 import xml.etree.ElementTree as ET 19 20 tree = ET.parse("xmltest.xml") 21 root = tree.getroot() 22 23 #修改 24 for node in root.iter('year'): 25 new_year = int(node.text) + 1 #2008+1=2009 26 node.text = str(new_year) 27 node.set("updated","yes") #修改通过set,加个属性yes 28 29 tree.write("xmltest.xml") 30 31 #执行结果:
    会生成一个新的xmltest.xml文件,内容中会添加
    <year updated="yes">2009</year> #年份+1,加个yes属性

    32 #删除node 33 for country in root.findall('country'): #通过对country进行遍历 34 rank = int(country.find('rank').text) #再用find找到rank 35 if rank > 50: #再判断>50的值 36 root.remove(country) #再用remove删除 37 38 tree.write('output.xml') #写到一个新文件中

    #执行结果:
    复制代码

    自己创建xml文档:

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

    执行结果:

    会生成一个test.xml的文件,文件内容如下:

    复制代码
     1 <?xml version='1.0' encoding='utf-8'?>
     2 
     3 <namelist>
     4     <name enrolled="yes">
     5         <age checked="no" />
     6         <sex>33</sex>
     7     </name>
     8     <name enrolled="no">
     9         <age>19</age>
    10     </name>
    11 </namelist>
    复制代码

    xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

    复制代码
     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 child in root:
     9     print(child.tag, child.attrib)
    10     for i in child:
    11         print(i.tag,i.text)
    12  
    13 #只遍历year 节点
    14 for node in root.iter('year'):
    15     print(node.tag,node.text)

    #执行结果:
    year 2008
    year 2011
            year 2011 16 #--------------------------------------- 17 18 import xml.etree.ElementTree as ET 19 20 tree = ET.parse("xmltest.xml") 21 root = tree.getroot() 22 23 #修改 24 for node in root.iter('year'): 25 new_year = int(node.text) + 1 #2008+1=2009 26 node.text = str(new_year) 27 node.set("updated","yes") #修改通过set,加个属性yes 28 29 tree.write("xmltest.xml") 30 31 #执行结果:
    会生成一个新的xmltest.xml文件,内容中会添加
    <year updated="yes">2009</year> #年份+1,加个yes属性

    32 #删除node 33 for country in root.findall('country'): #通过对country进行遍历 34 rank = int(country.find('rank').text) #再用find找到rank 35 if rank > 50: #再判断>50的值 36 root.remove(country) #再用remove删除 37 38 tree.write('output.xml') #写到一个新文件中

    #执行结果:
    复制代码

    自己创建xml文档:

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

    执行结果:

    会生成一个test.xml的文件,文件内容如下:

    复制代码
     1 <?xml version='1.0' encoding='utf-8'?>
     2 
     3 <namelist>
     4     <name enrolled="yes">
     5         <age checked="no" />
     6         <sex>33</sex>
     7     </name>
     8     <name enrolled="no">
     9         <age>19</age>
    10     </name>
    11 </namelist>
    复制代码

    6.configparser模块

    configparser 模块作用: 用来读写配置文件。

    一、常见文档格式如下:
    1、先新建一个名字为confile文件,写入下面内容:

    复制代码
     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
    复制代码

    示例1:  写入一个文件

    复制代码
     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)
    复制代码

    执行结果:

    1 #会生成example1.ini文件,内容如下:
    2 [DEFAULT]
    3 compressionlevel = 9
    4 compression = yes
    5 serveraliveinterval = 45

    示例2: 生成多个键值对

    复制代码
     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)
    复制代码

    执行结果:

    复制代码
    #会生成example1.ini文件,内容如下:
    
    [DEFAULT]
    compression = yes
    compressionlevel = 9
    serveraliveinterval = 45
    
    [bitbucket.org]
    user = hg
    
    [topsecret.server.com]
    host port = 50022
    forwardx11 = no
    复制代码

    #-----------------------------------查询功能-------------------------------#
    示例3: 实现查询功能

    #查出键中user对应的值

    复制代码
    1 import configparser
    2 
    3 config = configparser.ConfigParser()
    4 config.read('example1.ini')              #先把文件读进来
    5 print(config['bitbucket.org']['User'])   #取出user的值
    6 print(config['DEFAULT']['Compression'])  #Compression的值
    7 print(config['topsecret.server.com']['ForwardX11'])   #ForwardX11的值
    复制代码

    执行结果:

    1 hg
    2 yes
    3 no

    示例4:取的是bitbucket.org键的值,他会把DEFAULT的一起打印出来
    DEFAULT的特殊功能:因为只要带DEFAULT键值对的,他就会把DEFAULT的键打印出来

    复制代码
    1 import configparser
    2 
    3 config = configparser.ConfigParser()
    4 config.read('example1.ini')          
    5 
    6 for key in config['bitbucket.org']:  #取的是bitbucket.org的值,他会把DEFAULT的一起打印出来
    7     print(key)
    复制代码

    执行结果:

    1 user
    2 compression
    3 compressionlevel
    4 serveraliveinterval

    示例5:
    取的是bitbucket.org键的值,以列表的方式打印出来

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

    执行结果:

    1 ['user', 'compression', 'compressionlevel', 'serveraliveinterval']

    示例6:
    取的是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')]

    示例7:
    连续取值,取出compression的值

    复制代码
    1 import configparser
    2 
    3 config = configparser.ConfigParser()
    4 config.read('example1.ini')
    5 
    6 print(config.get('bitbucket.org','compression'))   #取出compression的值
    复制代码

    执行结果:

    1 yes             #=====>取出的compression的值 yes

    #-------------------------------------增加功能----------------------------------#

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

    1、首先必须有一个example1.txt文件,里面内容为:

    复制代码
     1 [DEFAULT]
     2 serveraliveinterval = 45
     3 compression = yes
     4 compressionlevel = 9
     5 
     6 [bitbucket.org]
     7 user = hg
     8 
     9 [topsecret.server.com]
    10 host port = 50022
    11 forwardx11 = no
    复制代码

    2、增加一个块和键值对

    复制代码
    1 import configparser
    2 
    3 config = configparser.ConfigParser()
    4 config.read('example1.ini')    #从这里面拿到三个对象
    5 
    6 config.add_section('yuan')               #再新增加一个块
    7 config.set('yuan','k1','11111')          #给键添加键值对
    8 config.write(open('1.cfg', "w"))         #创建一个新文件
    复制代码

    执行结果:

    复制代码
     1 [DEFAULT]
     2 serveraliveinterval = 45
     3 compression = yes
     4 compressionlevel = 9
     5 
     6 [bitbucket.org]
     7 user = hg
     8 
     9 [topsecret.server.com]
    10 host port = 50022
    11 forwardx11 = no
    12 
    13 [yuan]          #这就是新增加的块
    14 k1 = 11111
    复制代码

    #-------------------------------------删除功能----------------------------------#
    示例1:

    1、首先必须有一个example1.txt文件,里面内容为:

    复制代码
     1 [DEFAULT]
     2 serveraliveinterval = 45
     3 compression = yes
     4 compressionlevel = 9
     5 
     6 [bitbucket.org]
     7 user = hg
     8 
     9 [topsecret.server.com]
    10 host port = 50022
    11 forwardx11 = no
    12 
    13 [yuan]   #这就是新增加的块
    14 k1 = 11111
    复制代码

    2、删除块和键值对的值

    复制代码
    1 import configparser
    2 
    3 config = configparser.ConfigParser()
    4 config.read('example1.ini')                     #从这里面拿到三个对象
    5 
    6 config.remove_section('topsecret.server.com')   #删除块和键值对的值
    7 config.remove_option('bitbucket.org','user')
    8 config.write(open('1.cfg', "w"))                #创建一个新文件
    复制代码

    执行结果:

    复制代码
    1 [DEFAULT]
    2 serveraliveinterval = 45
    3 compression = yes
    4 compressionlevel = 9
    5 
    6 [bitbucket.org]
    复制代码

     7.logging模块

     一、logging模块

    示例1:

    复制代码
    1 import logging  
    2 
    3 logging.debug('debug message')  
    4 logging.info('info message')  
    5 logging.warning('warning message')  
    6 logging.error('error message')  
    7 logging.critical('critical message')
    复制代码

    执行结果:  (默认是WARNING级别,所以只显示三条信息)

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

    日志级别:一般info就够用
    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING
    日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET(从高到低),默认的日志格式为日志级别:Logger名称:用户输出消息。

    示例2: 设置参数,调日志级别。调整为DEBUG级别,显示5条信息

    复制代码
     1 import logging
     2 
     3 logging.basicConfig(
     4 level=logging.DEBUG
     5 )
     6 
     7 logging.debug('debug message')
     8 logging.info('info message')
     9 logging.warning('warning message')
    10 logging.error('error message')
    11 logging.critical('critical message')
    复制代码

    执行结果: 显示5条信息

    1 DEBUG:root:debug message
    2 INFO:root:info message
    3 WARNING:root:warning message
    4 ERROR:root:error message
    5 CRITICAL:root:critical message

    示例3:  设置filename把日志写入到文件中,并参过加w参数,控制他每次只写5条,不重复的记录

    复制代码
     1 import logging
     2 
     3 logging.basicConfig(
     4 level=logging.DEBUG,           #默认信息显示在屏幕上面
     5 filename="logger.log",         #通过加filename参数,以追加的方式,把日志信息写入到文件中,每次重复运行都会往里面写5条记录
     6 filemode="w",                  #通过加w参数,就可以控制他,每次只写5条记录。不会重复往里写相同记录
     7 )
     8 
     9 logging.debug('debug message')
    10 logging.info('info message')
    11 logging.warning('warning message')
    12 logging.error('error message')
    13 logging.critical('critical message')
    复制代码

    执行结果:

    复制代码
    1 会创建一个logger.log日志,并写入五条记录
    2 DEBUG:root:debug message
    3 INFO:root:info message
    4 WARNING:root:warning message
    5 ERROR:root:error message
    6 CRITICAL:root:critical message
    复制代码

    示例4: 给logging加上参数,显示时间,行号等信息。

    复制代码
     1 import logging
     2 
     3 logging.basicConfig(
     4 level=logging.DEBUG,     #默认信息显示在屏幕上面
     5 filename="logger.log",   #通过加filename参数,以追加的方式,把日志信息写入到文件中,每次重复运行都会往里面写5条记录
     6 filemode="w",            #通过加w参数,就可以控制他,每次只写5条记录。不会重复往里写相同记录
     7 # format="%(asctime)s",  #加上时间
     8 format="%(asctime)s %(filename)s[%(lineno)d]  %(message)s"  #asctime 时间,lineno 行号,message 信息,还可以加其它信息参数
     9 )
    10 
    11 logging.debug('debug message')
    12 logging.info('info message')
    13 logging.warning('warning message')
    14 logging.error('error message')
    15 logging.critical('critical message')
    复制代码

    执行结果:

    复制代码
    1 会创建一个logger.log日志,并写入五条记录
    2 2016-12-15 14:10:33,615 logging_s1.py[15]  debug message
    3 2016-12-15 14:10:33,616 logging_s1.py[16]  info message
    4 2016-12-15 14:10:33,616 logging_s1.py[17]  warning message
    5 2016-12-15 14:10:33,616 logging_s1.py[18]  error message
    6 2016-12-15 14:10:33,617 logging_s1.py[19]  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用户输出的消息

    二、logger对象(自定义日志格式,经常用的一种方法) 重点掌握

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

    原理图:

    示例1:

    复制代码
     1 import logging
     2 
     3 logger=logging.getLogger()         #创建一个大对象
     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吃掉
    14 logger.addHandler(ch)   #对象,类似于吸别人内力,把ch吃掉
    15 
    16 logger.debug("debug")   #输出日志的级别
    17 logger.info("info")
    18 logger.warning("warning")
    19 logger.error("error")
    20 logger.critical("critical")
    复制代码

    执行结果:

    复制代码
     1 会生成一个test_log的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
     2 文件内容如下:
     3 2016-12-15 14:38:27,657  warning
     4 2016-12-15 14:38:27,658  error
     5 2016-12-15 14:38:27,658  critical
     6 
     7 屏幕输出信息如下:
     8 2016-12-15 14:38:27,657  warning
     9 2016-12-15 14:38:27,658  error
    10 2016-12-15 14:38:27,658  critical
    复制代码

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

    复制代码
     1 import logging
     2 
     3 logger=logging.getLogger()         #创建一个大对象
     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吃掉
    14 logger.addHandler(ch)    #对象,类似于吸别人内力,把ch吃掉
    15 logger.setLevel("DEBUG") #设置日志级别,控制日志输入多少条信息
    16 
    17 
    18 #-------------从这里开始都是在操作log----------------
    19 
    20 logger.debug("debug")   #输出日志的级别
    21 logger.info("info")
    22 logger.warning("warning")
    23 logger.error("error")
    24 logger.critical("critical")
    复制代码

    执行结果:

    复制代码
     1 会生成一个test_log的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
     2 文件内容如下:
     3 2016-12-15 14:54:37,036  debug
     4 2016-12-15 14:54:37,037  info
     5 2016-12-15 14:54:37,038  warning
     6 2016-12-15 14:54:37,038  error
     7 2016-12-15 14:54:37,039  critical
     8 
     9 屏幕输出信息如下:
    10 2016-12-15 14:54:37,036  debug
    11 2016-12-15 14:54:37,037  info
    12 2016-12-15 14:54:37,038  warning
    13 2016-12-15 14:54:37,038  error
    14 2016-12-15 14:54:37,039  critical
    复制代码

    示例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")
    复制代码

    执行结果:

    复制代码
     1 会生成一个test_log的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
     2 文件内容如下:
     3 2016-12-15 14:54:37,036  debug
     4 2016-12-15 14:54:37,037  info
     5 2016-12-15 14:54:37,038  warning
     6 2016-12-15 14:54:37,038  error
     7 2016-12-15 14:54:37,039  critical
     8 
     9 屏幕输出信息如下:
    10 2016-12-15 14:54:37,036  debug
    11 2016-12-15 14:54:37,037  info
    12 2016-12-15 14:54:37,038  warning
    13 2016-12-15 14:54:37,038  error
    14 2016-12-15 14:54:37,039  critical
    复制代码

    示例4: 只在屏幕文件中写入日志,不在屏幕上面显示

    复制代码
     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")
    复制代码

    执行结果:

    复制代码
    1 #会生成一个test_log的文件,同时往里面写入信息,不会在屏幕上面显示信息。
    2 #文件内容如下:
    3 2016-12-15 14:54:37,036  debug
    4 2016-12-15 14:54:37,037  info
    5 2016-12-15 14:54:37,038  warning
    6 2016-12-15 14:54:37,038  error
    7 2016-12-15 14:54:37,039  critical
    复制代码

    示例5:没有根用户
    #如果我们再创建两个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 logger1 and logger2各打印4条信息
     2 生成一个test_log-new的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
     3 文件内容如下:
     4 logger1 info message
     5 logger1 warning message
     6 logger1 error message
     7 logger1 critical message
     8 logger2 info message
     9 logger2 warning message
    10 logger2 error message
    11 logger2 critical message
    12 
    13 #屏幕上面显示的内容
    14 logger1 info message
    15 logger1 warning message
    16 logger1 error message
    17 logger1 critical message
    18 logger2 info message
    19 logger2 warning message
    20 logger2 error message
    21 logger2 critical message
    复制代码

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

    示例7:添加根用户  (控制根用户不输入,只输出子用户信息)

    复制代码
     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 logger1.addHandler(fh)                      #添加一个子用户
    12 logger1.addHandler(ch)
    13 
    14 #打印4条信息
    15 logger1.debug('logger1 debug message')
    16 logger1.info('logger1 info message')
    17 logger1.warning('logger1 warning message')
    18 logger1.error('logger1 error message')
    19 logger1.critical('logger1 critical message')
    复制代码

    执行结果:

    复制代码
    #生成一个test_log-new的文件,同时往里面写入信息,并在屏幕上面显示相同信息。
    文件内容如下:
    logger1 debug message
    logger1 info message
    logger1 warning message
    logger1 error message
    logger1 critical message
    
    屏幕输出内容如下:
    logger1 debug message
    logger1 info message
    logger1 warning message
    logger1 error message
    logger1 critical message
    复制代码

     8.hashlib模块

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

    md5算法 明文变成密文

    示例1: md5算法

    1 import hashlib
    2 
    3 obj=hashlib.md5()
    4 obj.update("admin".encode("utf8"))
    5 print(obj.hexdigest())   

    执行结果:

    1 21232f297a57a5a743894a0e4a801fc3 (长度32位)

    示例2:

    复制代码
    1 import hashlib
    2 
    3 #md5加密+字符串,生成密码。就无法破解
    4 obj=hashlib.md5("sssdsdsb".encode("utf8"))   #在md5里面加点字符串,再生成,就没法破解
    5 obj.update("admin".encode("utf8"))
    6 
    7 print(obj.hexdigest())
    复制代码

    执行结果:

    1 639cd764cf1bab2bebaa5804e37530e6

    示例3:
    以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

    ####### 256 位########

    1 import hashlib
    2 
    3 hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
    4 hash.update('alvin'.encode('utf8'))
    5 print(hash.hexdigest())  

    执行结果:

    1 e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7

    示例4:
    python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密:

    1 import hmac
    2 
    3 h = hmac.new('alvin'.encode('utf8'))
    4 h.update('hello'.encode('utf8'))
    5 print (h.hexdigest())

    执行结果:

    1 320df9832eab4c038b6c1d7ed73a5940

    9.json&pickle模块

    用于序列化的两个模块

    • json,用于字符串 和 python数据类型间进行转换
    • pickle,用于python特有的类型 和 python的数据类型间进行转换

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

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

    10.Subprocess模块

    The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:

    os.system
    os.spawn*

    The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.

    The run() function was added in Python 3.5; if you need to retain compatibility with older versions, see the Older high-level API section.

    subprocess.run(args*stdin=Noneinput=Nonestdout=Nonestderr=Noneshell=Falsetimeout=Nonecheck=False)

    Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.

    The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the use of keyword-only notation in the abbreviated signature). The full function signature is largely the same as that of the Popen constructor - apart from timeoutinput and check, all the arguments to this function are passed through to that interface.

    This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.

    The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.

    The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if universal_newlines=True. When used, the internal Popen object is automatically created withstdin=PIPE, and the stdin argument may not be used as well.

    If check is True, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.

    常用subprocess方法示例

    #执行命令,返回命令执行状态 , 0 or 非0
    >>> retcode = subprocess.call(["ls", "-l"])

    #执行命令,如果命令结果为0,就正常返回,否则抛异常
    >>> subprocess.check_call(["ls", "-l"])
    0

    #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 
    >>> subprocess.getstatusoutput('ls /bin/ls')
    (0, '/bin/ls')

    #接收字符串格式命令,并返回结果
    >>> subprocess.getoutput('ls /bin/ls')
    '/bin/ls'

    #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
    >>> res=subprocess.check_output(['ls','-l'])
    >>> res
    b'total 0 drwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM '

    #上面那些方法,底层都是封装的subprocess.Popen
    poll()
    Check if child process has terminated. Returns returncode

    wait()
    Wait for child process to terminate. Returns returncode attribute.


    terminate() 杀掉所启动进程
    communicate() 等待任务结束

    stdin 标准输入

    stdout 标准输出

    stderr 标准错误

    pid
    The process ID of the child process.

    #例子
    >>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
    >>> p.stdout.read()
    b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% / '

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> subprocess.run(["ls""-l"])  # doesn't capture output
    CompletedProcess(args=['ls''-l'], returncode=0)
     
    >>> subprocess.run("exit 1", shell=True, check=True)
    Traceback (most recent call last):
      ...
    subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
     
    >>> subprocess.run(["ls""-l""/dev/null"], stdout=subprocess.PIPE)
    CompletedProcess(args=['ls''-l''/dev/null'], returncode=0,
    stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null ')

    调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:

    1
    2
    = subprocess.Popen("find / -size +1000000 -exec ls -shl {} ;",shell=True,stdout=subprocess.PIPE)
    print(p.stdout.read())

    可用参数:

    • 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 -> 同意使用
    • startupinfo与createionflags只在windows下有效
      将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

    终端输入的命令分为两种:

    • 输入即可得到输出,如:ifconfig
    • 输入进行某环境,依赖再输入,如:python

    需要交互的命令示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import subprocess
     
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    obj.stdin.write('print 1 ')
    obj.stdin.write('print 2 ')
    obj.stdin.write('print 3 ')
    obj.stdin.write('print 4 ')
     
    out_error_list = obj.communicate(timeout=10)
    print out_error_list

    subprocess实现sudo 自动输入密码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import subprocess
     
    def mypass():
        mypass = '123' #or get the password from anywhere
        return mypass
     
    echo = subprocess.Popen(['echo',mypass()],
                            stdout=subprocess.PIPE,
                            )
     
    sudo = subprocess.Popen(['sudo','-S','iptables','-L'],
                            stdin=echo.stdout,
                            stdout=subprocess.PIPE,
                            )
     
    end_of_pipe = sudo.stdout
     
    print "Password ok Iptables Chains %s" % end_of_pipe.read()

      

                                           

  • 相关阅读:
    java数据类型
    索引的种类和优缺点
    IntelliJ IDEA 自动导入快捷键
    KTV点歌系统------LinkedList
    KTV 点歌系统------ArrayList
    超市购物程序
    awk 入门教程
    Git 分支开发规范
    私有镜像仓库Harbor设置https、http访问
    私有镜像仓库Harbor部署
  • 原文地址:https://www.cnblogs.com/lixiaoliuer/p/6286477.html
Copyright © 2011-2022 走看看