首页 > 代码库 > day--6_python常用模块

day--6_python常用模块

常用模块:

  1. time和datetime

  2. shutil模块

  3. radom

  4. string

  5. shelve模块

  6. xml处理

  7. configparser处理

  8. hashlib

  9. subprocess

  10. logging模块

  11. re正则表达式

    time模块

    time模块,即时间模

    import time    # 导入时间模块
    
    print(time.process_time())  # 返回处理时间,不包含sleep时间,mac上测试不出来
    
    print(time.asctime())  # 返回时间格式Mon Nov 14 10:07:07 2016
    
    print(time.localtime())  # 返回被点时间对象struct time:time.struct_time(tm_year=2016, tm_mon=11, tm_mday=14, tm_hour=10, tm_min=8, tm_sec=41, tm_wday=0, tm_yday=319, tm_isdst=0)
    
    print(time.altzone)   # 返回UTC时间差,以秒计算
    print(time.time())    # 返回时间戳
    
    ‘‘‘
    # 返回UTC时间的struc时间对象格式:
    time.struct_time(tm_year=2016, tm_mon=11, tm_mday=3,
    tm_hour=16, tm_min=14, tm_sec=11,
    tm_wday=3, tm_yday=308, tm_isdst=0)
    ‘‘‘
    print(time.gmtime(time.time()-900000))
    
    print(time.asctime(time.localtime()))   # 返回时间格式:Mon Nov 14 10:14:11 2016
    
    print(time.ctime())  # 返回格式:Mon Nov 14 10:15:12 2016
    
    # 日期字符串转换为时间戳
    time2 = time.strptime("2016/11/13 22:22:22", %Y/%m/%d %H:%M:%S) # 将日期字符串转换为时间对象
    print(time2)
    
    time2_stamp = time.mktime(time2)     # 将时间对象转换为时间戳
    print(time2_stamp)
    
    time2_time = time.asctime(time2)    # 将时间戳转换为时间格式
    print(time2_time)
    
    # 将时间戳转换为字符串格式
    time3 = time.gmtime(time2_stamp) # 返回时间对象
    print(time3)
    print(time.strftime(%Y/%m/%d %H:%M:%S, time3))   # 返回格式:2016/11/13 14:22:22

    datetime模块

    时间模块

    import datetime
    import time
    # 返回当前时间
    print(datetime.datetime.now())  # 返回格式:2016-11-14 10:32:10.415558
    
    #时间戳直接转换为日期格式
    print(datetime.datetime.fromtimestamp(time.time())) # 返回格式:2016-11-14 10:32:10.415558
    
    # 当前时间加3天
    print(datetime.datetime.now() + datetime.timedelta(3))  # 返回结果:2016-11-17 10:43:07.668299
    
    # 当前时间减3天
    print(datetime.datetime.now() - datetime.timedelta(3))  # 返回结果2016-11-11 10:43:07.668299
    
    # 当前时间加3小时
    print(datetime.datetime.now() - datetime.timedelta(hours=3))  # 返回结果2016-11-14 07:43:07.668299
    
    # 当前时间减30分钟
    
    print(datetime.datetime.now() - datetime.timedelta(minutes=30))  # 返回结果:2016-11-14 10:13:07.668299
    
    # 时间替换
    c_time = datetime.datetime.now()    # 返回2016-11-14 10:54:44.986484
    print(c_time.replace(minute=3,hour=2))  # 返回:2016-11-14 02:03:44.986484

    常用时间字符

    directive 英文含义 中文含义
    %a Locale’s abbreviated weekday name. sun(sunday简写)
    %A Locale’s full weekday name. sunday(完整显示)
    %b Locale’s abbreviated month name. 英文1到12月简写
    %B Locale’s full month name. 英文1到12月完整的月名字
    %c Locale’s appropriate date and time representation.  
    %d Day of the month as a decimal number [01,31]. 一个月【01,31】
    %H Hour (24-hour clock) as a decimal number [00,23]. 24小时制【00-23】
    %I

    Hour (12-hour clock) as a decimal number [01,12].

    12小时制【01-12】
    %j Day of the year as a decimal number [001,366]. 天的显示【001-366】
    %m Month as a decimal number [01,12]. 月【01-12】
    %M Minute as a decimal number [00,59] 分钟【00-59】
    %p Locale’s equivalent of either AM or PM. AM上午
    PM 下午
    %S Second as a decimal number [00,61].
    %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. 一年的第多少周
    %w Weekday as a decimal number [0(Sunday),6]. 一周7天显示【0-6】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.  
    %x Locale’s appropriate date representation.  
    %X

    Locale’s appropriate time representation.

     
    %y Year without century as a decimal number [00,99]. 2016年显示16年
    %Y Year with century as a decimal number. 2016年显示2016年
    %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.

     

    radom随机数

    随机数模块

    import random  # 导入随机数模块
    import string  # 导入字符串模块
    
    print(random.random())  # 生成随机数
    
    print(random.randint(1, 5))  # 生成1-5的随机数包含5本身,每次显示一个
    
    print(random.randrange(1, 5))  # 生成1-5的随机数,不包含5本身,每次显示一个
    
    print(random.sample(range(10), 5))  # 生成5个随机数,格式为列表格式[7, 0, 1, 9, 5]
    
    # 生成随机验证码
    
    print(‘‘.join(random.sample(string.ascii_lowercase, 5)))  # 生成5个随机字母 返回:kbzdn
    
    print(‘‘.join(random.sample(string.ascii_letters, 5)))  # 生成5个随机验证码 返回:sNpGj
    
    
    # 生成随机验证码的另一种方法
    checkcode = ‘‘
    for i in range(4):
        current = random.randrange(0, 4)
        if current != i:
            ‘‘‘
            chr(random.randint(65, 90))将数字转换为ascii码的对应表
            chr(65) = A,chr(66) = B
            ‘‘‘
            temp = chr(random.randint(65, 90))
        else:
            temp = random.randint(0, 9)
        checkcode += str(temp)
    print(checkcode)

    string字符模块

    import string  # 导入字符串模块
    
    print(string.ascii_letters)  # 返回:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    print(string.ascii_lowercase)  # 返回:abcdefghijklmnopqrstuvwxyz
    
    print(string.ascii_uppercase)  # 返回:ABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    print(string.digits)  # 返回:0123456789
    
    print(string.hexdigits)  # 返回16进制:0123456789abcdefABCDEF
    
    print(string.octdigits)  # 返回8进制整数:01234567

    shutil

    # 高级的 文件、文件夹、压缩包处理模块
    例子1:shutil.copyfileobj()
    将文件内容拷贝到另一个文件中吗,可以拷贝部分内容:
    import shutil
    f = open(test.xml,r,encoding=utf-8)
     f1 = open(test_new.xml,w,encoding=utf-8)
    shutil.copyfileobj(f,f1) 
    # shutil.copyfileobj()方法需要打开文件才能拷贝
    例子2:shutil.copyfile()
    拷贝文件

    import shutil
    shutil.copyfile(test.xml,test_new_1.xml)

    例子3:

    shutil.copymode(stc,dst)

    import shutil
    # shutil.copymode(stc,dst)  # 仅拷贝权限,内容、组用户均不变
    # src源文件,dst目标
    shutil.copymode(test.xml, test_new_1.xml)

    例子4:shutil.copy(stc,dst)

    # 拷贝文件和权限

    import shutil
    
    # 拷贝文件和权限
    # shutil.copy(stc,dst)
    shutil.copy(test.xml, test_new_1.xml)

    例子5:shutil.copy2() 拷贝文件和状态信息

    import shutil
    # shutil.copy2() 拷贝文件和状态信息
    shutil.copystat(test.xml, test_new_1.xml)

    例子6:shutil.copystat() 拷贝文件和状态信息

    import shutil
    # shutil.copystat() 拷贝文件和状态信息
    shutil.copystat(test.xml, test_new_1.xml)

    例子7:shutil.copy2(src, dst)

    import shutil
    # shutil.copy2(src, dst)
    # 拷贝文件和状态信息
    shutil.copy2(test.xml, test_new_1.xml)

    例子8:shutil.make_archive(base_name, format,...)

    创建压缩包并返回文件路径,例如:zip、tar

    • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
      如:www                        =>保存至当前路径
      如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    • root_dir: 要压缩的文件夹路径(默认当前目录)
    • owner: 用户,默认当前用户
    • group: 组,默认当前组
    • logger: 用于记录日志,通常是logging.Logger对象

    # 将D:\python_progream\python_s15\day6 下的文件打包放置当前程序目录
    import shutil
    ret = shutil.make_archive("start", format=zip, root_dir=D:\python_progream\python_s15\day6)

    结果:

    技术分享

    zipfile模块

    zip压缩,shutil对压缩包的处理是调用zipfile和taifile模块来进行的

    zipfile代码

    import zipfile
    
    # 压缩
    z = zipfile.ZipFile(testabc.zip, w)
    z.write(xml_mode.py)
    z.write(timelog.log)
    z.close()
    
    # 解压
    z = zipfile.ZipFile(laxi.zip, r)
    z.extractall()
    z.close()
    #
    # zipfile 压缩解压

     

    tarfile代码

    import tarfile
    
    # 压缩
    tar = tarfile.open(your.tar,w)
    tar.add(/Users/xiaofeng/PycharmProjects/bbs2.zip, arcname=bbs2.zip)
    tar.add(/Users/xiaofeng/PycharmProjects/cmdb.zip, arcname=cmdb.zip)
    tar.close()
    
    # 解压
    tar = tarfile.open(xxx.tar,r)
    tar.extractall()  # 可设置解压地址
    tar.close()
    
    tarfile 压缩解压

    shelve模块

    shelve模块是一个简单的k,v将内存数据通过文件持久化模块,可以持久化pickle可支持的python数据格式

    要使用shelve模块,必须要导入模块:import shelve

    import shelve
    
    f = shelve.open(shelve_test) #打开一个文件
    
    def stu(name, age):
        print(stu,name, age)
    t2 = (1, 2, 3, 4)
    name = ["aaa", "rain", "test"]
    f["test"] = name  # 持久化列表
    f["t2"] = t2    # 持久化元组
    f["func"] = stu  # 持久化函数
    
    f.close()

    shleve读取

    import shelve
    
    def stu(name, age):
        print(stu, name, age)
        return 0
    f = shelve.open(shelve_test)
    print(f["test"])   # 返回[‘aaa‘, ‘rain‘, ‘test‘]
    print(f["test"][1])  # 返回:rain
    print(f[t2])     # 返回:(1, 2, 3, 4)
    print(f[t2][2])  # 返回:3
    print(f["func"](xao, 22))   # 返回:stu xao 22

    xml处理模块

    xml是实现不同语言或程序之间进行数据交换协议,跟json差不多,但是json使用起来简单,不过,古时候,在json还没有诞生的年代,大家只能用xml,只进很多传统公司还在用xml

    xml格式如下,就是通过<>节点来区别数据结构的:

    <?xml version="1.0"?>
    <data>
        <country name="Liechtenstein">
            <rank updated="yes">2</rank>
            <year>2008</year>
            <gdppc>141100</gdppc>
            <neighbor name="Austria" direction="E"/>
            <neighbor name="Switzerland" direction="W"/>
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year>2011</year>
            <gdppc>59900</gdppc>
            <neighbor name="Malaysia" direction="N"/>
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year>2011</year>
            <gdppc>13600</gdppc>
            <neighbor name="Costa Rica" direction="W"/>
            <neighbor name="Colombia" direction="E"/>
        </country>
    </data>

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

    如果要操作xml格式的文件

    首先需要引入xml相关模块

    import xml.etree.ElementTree as ET
    tree = ET.parse("test.xml")
    root = tree.getroot()
    print(root.tag)   # tag首行
    # for child in root:
    #     print(child.tag, child.attrib)
    #     for i in child:
    #         print(i.tag, i.text)    # text打印值
    
    # 返回值:
    ‘‘‘
    data
    country {‘name‘: ‘Liechtenstein‘}
    rank 2
    year 2008
    gdppc 141100
    neighbor None
    neighbor None
    country {‘name‘: ‘Singapore‘}
    rank 5
    year 2011
    gdppc 59900
    neighbor None
    country {‘name‘: ‘Panama‘}
    rank 69
    year 2011
    gdppc 13600
    neighbor None
    neighbor None
    ‘‘‘
    
    # 只遍历year节点
    # for node in root.iter(‘year‘):
    #     print(node.tag, node.text)
    # 返回值:
    ‘‘‘
    year 2008
    year 2011
    year 2011
    ‘‘‘
    
    #  修改
    # 遍历所有年并修改年的值+1
    for node in root.iter(year):
        new_year = int(node.text) + 1  # 所有的年的值加1
        node.text = str(new_year)   # 将new_year中的数字转换为字符串
        node.set("updated", "yes")  # 所有的年添加属性
    tree.write("test1.xml")
    
    # 删除
    # 删除node
    for country in root.findall(country):  # findall查找所有
        rank = int(country.find(rank).text)  # 将rank的值付给rank,并转换为整数
        if rank > 50:
            root.remove(country)    # 移除一个country标签
    tree.write(test2.xml)
    
    # 创建一个xml文件
    new_xml = ET.Element("dev")  # 创建根标签,dev为根标签的名字
    name = ET.SubElement(new_xml, "name", attrib={"enrolled":"yes"}) # 创建子标签,子标签的名字为name
    # attrib指定属性
    # 返回值
    age = ET.SubElement(name, "age", attrib={"enrolled":"yes"}) # 设置name的子标签age,并设置属性
    sex = ET.SubElement(name, "sex")  # 设置子标签中的子标签
    sex.text = 33   # 设置sex的值
    et = ET.ElementTree(new_xml)
    et.write("test3.xml", encoding="utf-8",xml_declaration=True)
    # 返回值:<?xml version=‘1.0‘ encoding=‘utf-8‘?>
    # ET.dump(test3.xml) #打印生成的格式

    生成的文件

    <?xml version=‘1.0‘ encoding=‘utf-8‘?>
    <dev> 
        <name enrolled="yes">
            <age enrolled="yes" /> 
            <sex>33</sex>
        </name>
    </dev>

    configparser模块

    用于生成常见的配置文档,当前名称在python3版本中变更为configparser,在2版本中首字母是大写。

    configparser生成的常见配置文件如下:

    [DEFAULT]
    ServerAliveInterval = 45
    Compression = yes
    CompressionLevel = 9
    ForwardX11 = yes
     
    [bitbucket.org]
    User = hg
     
    [topsecret.server.com]
    Port = 50022
    ForwardX11 = no

    如果想用python生成一个这样的文档怎么做:

    import configparser
    config = configparser.ConfigParser()
    config["DEFAULT"] = {ServerAliveInterval: 45,
                          Compression: yes,
                         CompressionLevel: 9}
    config[xuanchuan.org] = {}
    config[xuanchuan.org][user] = hg
    config[top.server.com] = {}
    top = config[top.server.com]
    top[Host Port] = 56666
    top[ForwardX11] = no
    config["DEFAULT"][ForwardX11] = yes
    with open(config.ini,w) as f:
        config.write(f)

    粘贴结果:

    [DEFAULT]
    compressionlevel = 9
    serveraliveinterval = 45
    compression = yes
    forwardx11 = yes
    
    [xuanchuan.org]
    user = hg
    
    [top.server.com]
    host port = 56666
    forwardx11 = no

    config.ini文件操作:

    # 读取config.ini文件
    import configparser
    config = configparser.ConfigParser()
    config.sections()
    
    print(config.read(config.ini))  # 返回值[‘config.ini‘]
    print(config.sections())   # 返回:[‘xuanchuan.org‘, ‘top.server.com‘],默认[DEFAULT]不读取
    print(config["DEFAULT"][forwardx11])  # 返回值:yes
    print(config[top.server.com][Host Port])  # 返回值:56666,此处key是不区分大小写的
    
    # 遍历config.ini文件
    for key in config[top.server.conf]:
        print(key)
    
    # 改‘
    config[top.server.com][Host Port] = 222
    print(config[top.server.com][Host Port])
    with open(config1.ini, w) as f:
        config.write(f)

    hashlib模块

    用于加密的模块,3.x里代替了md5模块和sha模块,主要提供sha1,sha224,sha256,sha384,sha512,MD5算法

    import hashlib
    m = hashlib.md5()
    m.update(bhello)
    # print(m.digest())  # 二进制格式的hash
    print(m.hexdigest())  # 16禁止格式的hash
    # 返回值:5d41402abc4b2a76b9719d911017c592
    ###md5算法
    m.update(badmin)
    print(m.hexdigest())
    # 返回值:dbba06b11d94596b7169d83fed72e61b
    
    # # sha1算法
    sha_1 = hashlib.sha1()
    sha_1.update(b"admin")
    print(sha_1.hexdigest())
    # 返回值:d033e22ae348aeb5660fc2140aec35850c4da997
    
    # ##sha224算法
    sha_224 = hashlib.sha224()
    sha_224.update(b"admin")
    print(sha_224.hexdigest())
    # 返回值:58acb7acccce58ffa8b953b12b5a7702bd42dae441c1ad85057fa70b
    
    # ## sha256算法
    sha_256 = hashlib.sha256()
    sha_256.update(b"admin")
    print(sha_256.hexdigest())
    # 返回值:8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
    
    # ## sha384算法
    sha_384 = hashlib.sha384()
    sha_384.update(b"admin")
    print(sha_384.hexdigest())
    # 返回值:9ca694a90285c034432c9550421b7b9dbd5c0f4b6673f05f6dbce58052ba20e4248041956ee8c9a2ec9f10290cdc0782
    
    # ## sha512算法
    sha_512 = hashlib.sha512()
    sha_512.update(b"admin")
    print(sha_512.hexdigest())
    # 返回值:c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec

    hmac模块

    加严算法

    import hmac   # 引入模块,用于消息传输,类似于QQ消息
    h = hmac.new(balber)
    h.update(b"hello")
    print(h.hexdigest())
    # 返回值:1b6752f035a051eb026c3824de78a714
    # 或者
    h = hmac.new(balber,bhello)
    print(h.hexdigest())
    # 返回值:1b6752f035a051eb026c3824de78a714

    logging模块

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

    最简单的用法:

    此处需要粘贴代码

    下面看下这几个日志级别分别代表什么含义:

    level when it‘s used
    DEBUG 调试错误
    INFO 相信信息
    WARNING 警告信息
    ERROR 错误信息
    CRIITICAL  

    如果想把日志写到文件也很简答:

    import logging
    logging.basicConfig(filename=log.log,level=logging.DEBUG) #默认是追加模式a
    logging.debug("this is debug")
    logging.info("this is info")
    logging.warning("user[alber] attempet warning")
    logging.critical("mysql server is down")

    日志文件:

    DEBUG:root:this is debug
    INFO:root:this is info
    WARNING:root:user[alber] attempet warning
    CRITICAL:root:mysql server is down

    日志格式format=

    %(thread)d线程ID。可能没有
    %(name)s logger的名字
    %(levelno)s 数字形式的日志级别
    %(levelname)s 文本格式的日志级别
    %(pathname)s 调用日志输出函数的模块的完成路径名,可能没有
    %(filename)s 调用日志输出函数的模块的文件名
    %(module)s 调用日志输出函数的模块名
    %(funcName)s 调用日志输出函数的函数名
    %(lineno)d 调用日志输出函数的语句所在的代码行
    %(created)f 当前时间,用unix标准的表示时间的浮点数表示
    %(relactiveCreated)d 输出日志信息时,自logger创建以来的毫秒数
    %(asctime)s 字符串形式的当前时间。默认格式“2003-07-08 16:49:45,896”。逗号后面是毫秒数
    %(thread)d 线程ID。可能没有
    %(threadName)s 线程名。可能没有
    %(process)d 进程ID。可能没有
    %(message)s 用户输出的消息

    例子:

    import logging
    logging.basicConfig(filename=log.log,level=logging.DEBUG) #默认是追加模式a
    logging.debug("this is debug")
    logging.info("this is info")
    logging.warning("user[alber] attempet warning")
    logging.critical("mysql server is down")
    
    # 返回值:log.log文件
    
    logging.basicConfig(filename=log.log, level=logging.DEBUG,
                        format=%(asctime)s  %(levelname)s:%(message)s,
                        datefmt=%Y-%m-%d %I:%M:%S %p)  # 默认是追加模式a
    logging.debug("this is debug")
    logging.info("this is info")
    logging.warning("user[alber] attempet warning")
    logging.critical("mysql server is down")
    
    logger = logging.getLogger("nginx")  # 指定程序名
    logger.setLevel(logging.DEBUG)   #设定程序的日志级别

    日志文件:

    2016-11-14 05:34:02 PM  WARNING: user[alber] attempet warning
    2016-11-14 05:34:02 PM  CRITICAL: mysql server is down
    2016-11-14 05:34:17 PM  DEBUG:this is debug
    2016-11-14 05:34:17 PM  INFO:this is info
    2016-11-14 05:34:17 PM  WARNING:user[alber] attempet warning
    2016-11-14 05:34:17 PM  CRITICAL:mysql server is down

    如果想同时把log打印在屏幕和日志文件里,就要了解复杂的知识了

    python使用logging模块记涉及四个主要类,使用官方文档的概述最为合适:

    logger提供了应用程序可以直接使用接口

    handler将(logger创建)日志记录发送到合适的目的输出

    filter提供了细度设备来决定输出哪条日志记录

    formatter决定记录日志的最终输出格式

    logger

    每个程序在输出信息之前偶要获得一个logger。logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的logger:

    log=logging.getlogger("char.gui")

    而核心模块可以这样

    log=logging.getlogger("kerenel")

    logger.setLevel(level):指定日志最低级别,低于level的级别将被忽略,debug是最低的内置级别,critical为最高

    logger.addFilter(filt),Logger.removeFilter(filt):添加或删除指定的filter

    Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler

    Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

    handler

    handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

    Handler.setLevel(level):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
    1) logging.StreamHandler
    使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
    StreamHandler([strm])
    其中strm参数是一个文件对象。默认是sys.stderr

    2) logging.FileHandler
    和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
    FileHandler(filename[,mode])
    filename是文件名,必须指定一个文件名。
    mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a‘,即添加到文件末尾。

    3) logging.handlers.RotatingFileHandler
    这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
    RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
    其中filename和mode两个参数和FileHandler一样。
    maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
    backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

    4) logging.handlers.TimedRotatingFileHandler
    这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
    TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
    其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
    interval是时间间隔。
    when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
    S 秒
    M 分
    H 小时
    D 天
    W 每星期(interval==0时代表星期一)
    midnight 每天凌晨

    例子:

    import logging
    logger = logging.getLogger("nginx")  # 指定程序名
    logger.setLevel(logging.DEBUG)   #设定程序的日志级别
    
    # 指定log的显示方式
    ch = logging.StreamHandler()  # 显示器屏幕方式输入
    ch.setLevel(logging.DEBUG)    # 显示器屏幕输入的日志级别
    
    fh = logging.FileHandler(access.log)  # 显示器文件输出,access.log是日志文件名字
    fh.setLevel(logging.WARNING)  # 显示器文件输出的日志级别
    
    # 指定日志格式
    formatter = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s)
    
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
    
    logger.addHandler(ch)
    logger.addHandler(fh)
    
    logger.debug("this is debug")
    logger.info("this is info")
    logger.warning("user[alber] attempet warning")
    logger.critical("mysql server is down")

    日志文件:

    2016-11-14 18:22:45,612 - nginx - WARNING - user[alber] attempet warning
    2016-11-14 18:22:45,613 - nginx - CRITICAL - mysql server is down

    日志切割例子:

    import logging
    from logging import handlers
    
    logger = logging.getLogger("nginx")
    
    log_file = "timelog.log"
    
    # 以大小切割
    #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
    # maxBytes,多少字节切割,backupCount,保留的分数
    
    # 以时间切割
    fh = handlers.TimedRotatingFileHandler(filename=log_file,
                                           when="S", interval=5, backupCount=3)
    # when= ‘S‘ 指定单位为秒 interval= 5 表示5面切割,backupCount=3,备份三份
    
    formatter = logging.Formatter(%(asctime)s %(module)s:%(lineno)d %(message)s)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    logger.warning("test1")
    logger.warning("test12")
    logger.warning("test13")
    logger.warning("test14")

    re模块

    常用的正则表达式模块

    符号

    含义

    .

    默认匹配除\n之外的任意一个字符,若指定gflag DOTALL,则匹配任意字符,包括换行

    ^

    匹配字符开头,若指定flag MULTILINE这中也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)

    $

    匹配以字符结尾,e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以

    *

    匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为[‘abb‘, ‘ab‘, ‘a‘]

    +

    匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果[‘ab‘, ‘abb‘]

    ‘?‘

    匹配前面的字符一次或0次

    ‘{m}‘

    匹配前一个字符m次

    ‘{n,m}‘

    匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果‘abb‘, ‘ab‘, ‘abb‘]

    ‘|‘

    匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果‘ABC‘

    ‘(...)‘

    分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c

    ‘\A‘

    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的

    ‘\Z‘

    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的

    ‘\d‘

    匹配数字0-9

    ‘\D‘

    匹配非数字

    \w‘

    匹配[A-Za-z0-9]

    ‘\W‘

    匹配非[A-Za-z0-9]

    ‘s‘

    匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 ‘\t‘

    ‘(?P<name>...)‘

    分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{‘province‘: ‘3714‘, ‘city‘: ‘81‘, ‘birthday‘: ‘1993‘}

    最常用的匹配语法

    re.match从头开始匹配

    re.search 配额包含

    re.findall 把所有匹配到的字符放在以列表中的元素返回

    re.splitall 以匹配到的字符当作列表分割符

    re.sub 匹配字符串并替换

    反斜杠的困扰
    与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

    仅需轻轻知道的几个匹配模式

    re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)

    M(MULTILINE): 多行模式,改变‘^‘和‘$‘的行为(参见上图)

    S(DOTALL): 点任意匹配模式,改变‘.‘的行为

    例子:

    day--6_python常用模块