码迷,mamicode.com
首页 > 其他好文 > 详细

常用模块

时间:2018-05-28 11:29:41      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:lod   概念   dom   wap   权限   SHA256   IV   传参   形式   

  • 一  time 与 datetime 模块

          

import time
print(time.time())
print(time.strftime("%Y-%m-%d %X"))
print(time.localtime())
print(time.gmtime())

  

 import time,datetime
 print(datetime.datetime.now())
 print(datetime.date.fromtimestamp(time.time()))
 print(datetime.datetime.now())
 print(datetime.datetime.now() + datetime.timedelta(hours=4))
 c_time = datetime.datetime.now()
 print(c_time.replace(minute=3,hour=2))

  

  • 二  random 模块

             

import random
print(random.random())    #---float   大于0且小于1之间的小数
print(random.randint(1,3))          #大于等于1且小于等于3之间的整数
print(random.randrange(1,3))        #大于等于1且小于3之间的整数
print(random.choice([1,‘23‘,[4,5]]))      #1或者23或者[4,5]
print(random.sample([1,‘23‘,[4,5]],2))     #列表元素任意2个组合
print(random.uniform(1,3)) #大于1小于3的小数
item=[1,3,5,7,9]
print(random.shuffle(item))       #打乱item的顺序,相当于洗牌

  

#生成随机验证码
import random
def make_code(n):
    res=‘‘
    for i in range(n):
        s1=chr(random.randint(65,90))
        s2=chr(random.randint(0,9))
        res +=random.choice([s1,s2])
        return res
print(make_code(9))

  

  • 三  os 模块

             

os路径处理
#方式一:推荐使用
import os
#具体应用
import os,sys
possible_topdir = os.path.normpath(os.path.join(
    os.path.abspath(__file__),
    os.pardir, #上一级
    os.pardir,
    os.pardir
))
sys.path.insert(0,possible_topdir)


#方式二:不推荐使用
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

 

  • 四  sys 模块

          1. sys.argv 命令行参数List,第一个元素是程序本身路径

          2. sys.exit(n)退出程序,正常退出时exit(0)

          3. sys.version  获取Python解释程序的版本信息

          4. sys.maxint     最大的Int值

          5. sys.path      返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

           6. sys.platform   返回操作系统平台名称

     ps: 打印进度条:

          

技术分享图片
#=========知识储备==========
#进度条的效果
[#             ]
[##            ]
[###           ]
[####          ]

#指定宽度
print([%-15s] %#)
print([%-15s] %##)
print([%-15s] %###)
print([%-15s] %####)

#打印%
print(%s%% %(100)) #第二个%号代表取消第一个%的特殊意义

#可传参来控制宽度
print([%%-%ds] %50) #[%-50s]
print(([%%-%ds] %50) %#)
print(([%%-%ds] %50) %##)
print(([%%-%ds] %50) %###)


#=========实现打印进度条函数==========
import sys
import time

def progress(percent,width=50):
    if percent >= 1:
        percent=1
    show_str=([%%-%ds] %width) %(int(width*percent)*#)
    print(\r%s %d%% %(show_str,int(100*percent)),file=sys.stdout,flush=True,end=‘‘)


#=========应用==========
data_size=1025
recv_size=0
while recv_size < data_size:
    time.sleep(0.1) #模拟数据的传输延迟
    recv_size+=1024 #每次收1024

    percent=recv_size/data_size #接收的比例
    progress(percent,width=70) #进度条的宽度70
打印进度条示例

 

  • 五  shutil 模块

       shutil.copyfileobj(fsrc,fdst[,length])    将文件内容拷贝到另一个文件中

       import shutil

       shutil.copyfileobj(open(‘old.xml‘,‘r‘),open(‘new.xml‘,‘w‘))

       shutil.copyfile(‘f1.log‘,‘f2.log‘)    #目标文件无需存在

       shutil.copymode(‘f1.log‘,‘f2.log‘)   #目标文件必须存在

       shutil.copy(src,dest)  拷贝文件和权限

       import shutil

       shutil.copy(‘f1.log‘,‘f2.log‘)

       shutil.copy2(src,dest)   拷贝文件和状态信息

       import shutil1

      shutil1.copy2(‘f1.log‘,‘f2.log‘)

      shutil.ignore_patterns(*patterns)

      shutil.copytree(src,dest,symlinks=False,ignore=None)  递归的去拷贝文件夹

      import shutil

     shutil.copytree(‘f1‘,‘f2‘,symlinks=Ture,ignore=shutil.ignore_patterns(‘*.pyc‘,‘tmp*‘))  #目标目录不能存在,注意对floder2目录父级目录要有可写权限,ignore的意思是排除

     拷贝软链接:

     import shutil

     shutil.copytree(‘f1‘,‘f2‘,symlinks=True,ignore=shutil.ignore_patterns(‘*.pyc‘,‘tmp*‘))        #通常的拷贝就是把软连接拷贝成硬连接,即对待软连接来说,创建新的文件

 

 

     shutil.rmtree(path[,ignore_errorsp[,onerror]])       #递推的去删除文件

     import shutil

     shutil.rmtree(‘folder1‘)

     shutil.move(src,dest)

     import shutil

    shutil.move(‘folder1‘,‘folder3‘)

    shutil.make_archive(base_name,format,......)

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

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

    >> base.name: 压缩包的文件名,也可以是压缩包的路径。只有文件名时,则保存至当前目录,否则保存至指定路径,如data_bak    ==>保存至当前路径,  如/tmp/data_bak   ==>保存至/tmp/

   >> format : 压缩包种类,"zip", "tar", "bztar","gztar"

   >> root_dir: 要压缩的文件夹路径(默认当前目录)

   >>owner: 用户,默认当前用户

   >>group : 组,默认当前组

  >>logger:用于记录日志,通常是logging.Logger 对象

 #将 /data 目录的文件打包放置当前程序目录

   import shutil

   ret=shutil.make_archive("data_bak",‘gztar‘,‘root_dir=‘/data‘

 #将/data目录下的文件打包放置/tmp/目录

   import shutil

   ret=shutil.make_archive("/tmp/data_bak",‘gztar‘,root_dir=‘/data‘

  shutil对压缩包的处理是调用ZipFile和TarFile两个模块来进行的,详细:

 # zipfile 压缩解压缩

  import zipfile

 #压缩

   z=zipfile.ZipFile(‘laxi.zip‘,‘w‘)

   z.write(‘a.log‘)

   z.write(‘data.data‘)

   z.close()

#解压

  z=zipfile.ZipFile(‘laxi.zip‘,‘r‘)

  z.extractall(path=‘.‘)

  z.close()

tarfile压缩解压缩

   import tarfile

#压缩

 >>> t=tarfile.open(‘/tmp/egon.tar‘,‘w‘)

 >>>t.add(‘/test1/a.py‘,arcname=‘a.bak‘)

 >>>t.add(‘/test1/b.py‘,arcname=‘b.bak‘)

 >>>t.close()

#解压

 >>> t=tarfile.open(‘/tmp/egon.tar‘,‘r‘)

>>>t.extractall(‘/egon‘)

>>>t.close() 

  • 六  json & pickle 模块

       import json

       x="[null,true,false,1]"

      print(eval(x))     #报错无法解析null类型,而json就可以

      print(json.loads(x))

     json 和python的内置数据如下表:

                    JSON

                Python

                      {}                  dict
                       []                  list
                  "string"                    str
                   1234.56              int/float
                   true/false             True/False
                       null                 None
  • 七 shelve 模块

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

        import shelve

        f=shelve.open(r ‘ sheve.txt‘)

        print(f[‘syu1_info‘][‘hobby‘])

        f.close()

  • 八 xml 模块

        xml 是实现不同语言或程序之前进行数据交换的协议,跟json 差不多,但json 使用起来更简单,不过,古时候,在json还没有诞生的黑暗时代,大家只能选择用xml呀,至今很多传统的金融行业的很多系统的         接口还主要是xml,xml的格式是通过<>节点来区别数据结构的,xml协议在各个语言里面都是支持的,再python中可以用一下模块操作xml:

       print(root.iter(‘year‘))     #全文搜索

       print(root.find(‘country‘))     #在root的子节点找,只找一个

       print(root.findall(‘country‘))    #在root 的子节点找,找所有

       在country内添加(append)节点year2

       import xml.etree.ElementTree as ET

       tree=ET.parse("a.xml")

       root=tree.getroot()

       for country in root.findall(‘country‘):

            for year in country.findall(‘year‘)

                  if int(year.text) >2000:

                     year2=ET.Element(‘year2‘)

                     year2.text=‘新年‘

                     year2.attrib={‘update‘:‘yes‘}

                     country.append(year2)     #往country节点下面添加子节点

                    tree.write(‘a.xml.swap‘)

  • 九 configparser 模块

   读取代码:

技术分享图片
import configparser

config=configparser.ConfigParser()
config.read(a.cfg)

#查看所有的标题
res=config.sections() #[‘section1‘, ‘section2‘]
print(res)

#查看标题section1下所有key=value的key
options=config.options(section1)
print(options) #[‘k1‘, ‘k2‘, ‘user‘, ‘age‘, ‘is_admin‘, ‘salary‘]

#查看标题section1下所有key=value的(key,value)格式
item_list=config.items(section1)
print(item_list) #[(‘k1‘, ‘v1‘), (‘k2‘, ‘v2‘), (‘user‘, ‘egon‘), (‘age‘, ‘18‘), (‘is_admin‘, ‘true‘), (‘salary‘, ‘31‘)]

#查看标题section1下user的值=>字符串格式
val=config.get(section1,user)
print(val) #egon

#查看标题section1下age的值=>整数格式
val1=config.getint(section1,age)
print(val1) #18

#查看标题section1下is_admin的值=>布尔值格式
val2=config.getboolean(section1,is_admin)
print(val2) #True

#查看标题section1下salary的值=>浮点型格式
val3=config.getfloat(section1,salary)
print(val3) #31.0
View Code

  改写代码:

技术分享图片
import configparser

config=configparser.ConfigParser()
config.read(a.cfg,encoding=utf-8)


#删除整个标题section2
config.remove_section(section2)

#删除标题section1下的某个k1和k2
config.remove_option(section1,k1)
config.remove_option(section1,k2)

#判断是否存在某个标题
print(config.has_section(section1))

#判断标题section1下是否有user
print(config.has_option(section1,‘‘))


#添加一个标题
config.add_section(egon)

#在标题egon下添加name=egon,age=18的配置
config.set(egon,name,egon)
config.set(egon,age,18) #报错,必须是字符串


#最后将修改的内容写入文件,完成最终的修改
config.write(open(a.cfg,w))
View Code
  • 十  hashlib 模块

              hash算法就像一座工厂,工厂接收你送来的原材料(可以m.update()为工厂运送原材料) ,经过加工返回的产品就是hash值

            import hashlib

            m=hashlib.md5()    #m=hashlib.sha256()

            m.update(‘hello‘.encode(‘utf8‘))

            print(m.hexdigest())

            m.update(‘alvin‘.encode(‘utf8‘))

            print(m.hexdigest())

           m2=hashlib.md5()

           m2=hashlib.md5()

           m2.update(‘helloalvin‘.encode(‘utf8‘))

           print(m2.hexdigest())

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

           import hmac

           h=hmac.new(‘alvin‘.encode(‘utf8‘))

           h.update(‘hello‘.encode(‘utf8‘))

           print(h.hexdigest())

         要想保证hmac最终结果一致,必须保证:

        1:hmac.new括号内指定的初始key一样

        2:无论update多少次,校验的内容累加到一起是一样的内容

          import hmac

          h1=hamc.new(b‘egon‘)

          h1.update(b‘hello‘)

         h1.update(b‘world‘)

         print(h1.hexdigest())

     

        h2=hmac.new(b‘egon‘)

        h2.update(b‘helloworld‘)

        print(h2.hexdigest())  

     

        h3=hmac.new(b‘egonhelloworle‘)

        print(h3.hexdigest())

   

  • 十一  suprocess 模块
技术分享图片
1 import  subprocess
 2 
 3 ‘‘‘
 4 sh-3.2# ls /Users/egon/Desktop |grep txt$
 5 mysql.txt
 6 tt.txt
 7 事物.txt
 8 ‘‘‘
 9 
10 res1=subprocess.Popen(ls /Users/jieli/Desktop,shell=True,stdout=subprocess.PIPE)
11 res=subprocess.Popen(grep txt$,shell=True,stdin=res1.stdout,
12                  stdout=subprocess.PIPE)
13 
14 print(res.stdout.read().decode(utf-8))
15 
16 
17 #等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
18 res1=subprocess.Popen(ls /Users/jieli/Desktop |grep txt$,shell=True,stdout=subprocess.PIPE)
19 print(res1.stdout.read().decode(utf-8))
20 
21 
22 #windows下:
23 # dir | findstr ‘test*‘
24 # dir | findstr ‘txt$‘
25 import subprocess
26 res1=subprocess.Popen(rdir C:\Users\Administrator\PycharmProjects\test\函数备课,shell=True,stdout=subprocess.PIPE)
27 res=subprocess.Popen(findstr test*,shell=True,stdin=res1.stdout,
28                  stdout=subprocess.PIPE)
29 
30 print(res.stdout.read().decode(gbk)) #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
View Code

 

  • 十二  logging 模块

     一  日志级别:

     CRITICAL = 50   #FATAL=CRITICAL

     ERROR = 40

     WARNING = 30   #WARN = WARNING

     INFO = 20

     BEBUG = 10

     NOTSET = 0     #不设置

     二 默认级别为 warning,默认打印到终端

    import logging

    logging.debug(‘调试debug‘)

    logging.info(‘消息info‘)

    logging.warning(‘警告warn‘)

    logging.error(‘错误error‘)

    logging.critical(‘严重critical‘)

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

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



#格式
%(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:用户输出的消息
View Code

  ======介绍=====

技术分享图片
可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为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用户输出的消息
View Code

  =====使用=====

技术分享图片
import logging
logging.basicConfig(filename=access.log,
                    format=%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
                    datefmt=%Y-%m-%d %H:%M:%S %p,
                    level=10)

logging.debug(调试debug)
logging.info(消息info)
logging.warning(警告warn)
logging.error(错误error)
logging.critical(严重critical)
View Code

  =====结果=====

技术分享图片
access.log内容:
2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug
2017-07-28 20:32:17 PM - root - INFO -test:  消息info
2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
2017-07-28 20:32:17 PM - root - ERROR -test:  错误error
2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重critical

part2: 可以为logging模块指定模块级的配置,即所有logger的配置
View Code

  四 logger模块的Formatter,Handler,Logger,Filter

     logger是第一级过滤,然后才能到handler,我们可以给logger和handler同时设置level,但是需要注意的是   

技术分享图片
Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still wont receive DEBUG messages on handlers — theyll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you wont receive any DEBUG messages either — because while the logger says "ok, process this", the handlers reject it (DEBUG < INFO).



#验证
import logging


form=logging.Formatter(%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
                    datefmt=%Y-%m-%d %H:%M:%S %p,)

ch=logging.StreamHandler()

ch.setFormatter(form)
# ch.setLevel(10)
ch.setLevel(20)

l1=logging.getLogger(root)
# l1.setLevel(20)
l1.setLevel(10)
l1.addHandler(ch)

l1.debug(l1 debug)
View Code

  五 logger 的配置文件

技术分享图片
"""
logging配置
"""

import os
import logging.config

# 定义三种日志输出格式 开始

standard_format = [%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]                   [%(levelname)s][%(message)s] #其中name为getlogger指定的名字

simple_format = [%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s

id_simple_format = [%(levelname)s][%(asctime)s] %(message)s

# 定义日志输出格式 结束

logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录

logfile_name = all2.log  # log文件名

# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)

# log配置字典
LOGGING_DIC = {
    version: 1,
    disable_existing_loggers: False,
    formatters: {
        standard: {
            format: standard_format
        },
        simple: {
            format: simple_format
        },
    },
    filters: {},
    handlers: {
        #打印到终端的日志
        console: {
            level: DEBUG,
            class: logging.StreamHandler,  # 打印到屏幕
            formatter: simple
        },
        #打印到文件的日志,收集info及以上的日志
        default: {
            level: DEBUG,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件
            formatter: standard,
            filename: logfile_path,  # 日志文件
            maxBytes: 1024*1024*5,  # 日志大小 5M
            backupCount: 5,
            encoding: utf-8,  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    loggers: {
        #logging.getLogger(__name__)拿到的logger配置
        ‘‘: {
            handlers: [default, console],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            level: DEBUG,
            propagate: True,  # 向上(更高level的logger)传递
        },
    },
}


def load_my_logging_cfg():
    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger(__name__)  # 生成一个log实例
    logger.info(It works!)  # 记录该文件的运行状态

if __name__ == __main__:
    load_my_logging_cfg()
View Code

   一.  使用        

技术分享图片
"""
MyLogging Test
"""

import time
import logging
import my_logging  # 导入自定义的logging配置

logger = logging.getLogger(__name__)  # 生成logger实例


def demo():
    logger.debug("start range... time:{}".format(time.time()))
    logger.info("中文测试开始。。。")
    for i in range(10):
        logger.debug("i:{}".format(i))
        time.sleep(0.2)
    else:
        logger.debug("over range... time:{}".format(time.time()))
    logger.info("中文测试结束。。。")

if __name__ == "__main__":
    my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置
    demo()
View Code

   二. !!!关于如何难道logger对象的详细解释!!!

技术分享图片
注意注意注意:


#1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理


#2、我们需要解决的问题是:
    1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)

    2、拿到logger对象来产生日志
    logger对象都是配置到字典的loggers 键对应的子字典中的
    按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的
    于是我们要获取不同的logger对象就是
    logger=logging.getLogger(loggers子字典的key名)

    
    但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key   
 loggers: {    
        l1: {
            handlers: [default, console],  #
            level: DEBUG,
            propagate: True,  # 向上(更高level的logger)传递
        },
        l2: {
            handlers: [default, console ], 
            level: DEBUG,
            propagate: False,  # 向上(更高level的logger)传递
        },
        l3: {
            handlers: [default, console],  #
            level: DEBUG,
            propagate: True,  # 向上(更高level的logger)传递
        },

}

    
#我们的解决方式是,定义一个空的key
    loggers: {
        ‘‘: {
            handlers: [default, console], 
            level: DEBUG,
            propagate: True, 
        },

}

这样我们再取logger对象时
logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=‘‘的配置
View Code

   三. django的配置,了解一下即可,跟上面的一样

技术分享图片
#logging_config.py
LOGGING = {
    version: 1,
    disable_existing_loggers: False,
    formatters: {
        standard: {
            format: [%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]
                      [%(levelname)s][%(message)s]
        },
        simple: {
            format: [%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s
        },
        collect: {
            format: %(message)s
        }
    },
    filters: {
        require_debug_true: {
            (): django.utils.log.RequireDebugTrue,
        },
    },
    handlers: {
        #打印到终端的日志
        console: {
            level: DEBUG,
            filters: [require_debug_true],
            class: logging.StreamHandler,
            formatter: simple
        },
        #打印到文件的日志,收集info及以上的日志
        default: {
            level: INFO,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自动切
            filename: os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
            maxBytes: 1024 * 1024 * 5,  # 日志大小 5M
            backupCount: 3,
            formatter: standard,
            encoding: utf-8,
        },
        #打印到文件的日志:收集错误及以上的日志
        error: {
            level: ERROR,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自动切
            filename: os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日志文件
            maxBytes: 1024 * 1024 * 5,  # 日志大小 5M
            backupCount: 5,
            formatter: standard,
            encoding: utf-8,
        },
        #打印到文件的日志
        collect: {
            level: INFO,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自动切
            filename: os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
            maxBytes: 1024 * 1024 * 5,  # 日志大小 5M
            backupCount: 5,
            formatter: collect,
            encoding: "utf-8"
        }
    },
    loggers: {
        #logging.getLogger(__name__)拿到的logger配置
        ‘‘: {
            handlers: [default, console, error],
            level: DEBUG,
            propagate: True,
        },
        #logging.getLogger(‘collect‘)拿到的logger配置
        collect: {
            handlers: [console, collect],
            level: INFO,
        }
    },
}


# -----------
# 用法:拿到俩个logger

logger = logging.getLogger(__name__) #线上正常的日志
collect_logger = logging.getLogger("collect") #领导说,需要为领导们单独定制领导们看的日志
View Code

  十三  re 模块

   正则就是用一些具有特殊含义的符号组合到一起(成为正则表达式)来描述字符或者字符串的方法。或者说正则就是用来描述一类事物的规则。常用的正则表达式匹配如下图:

    

常用模块

标签:lod   概念   dom   wap   权限   SHA256   IV   传参   形式   

原文地址:https://www.cnblogs.com/songyongqiang/p/9067511.html

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