• 模块


      在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

      为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。

    使用模块有什么好处?

    最大的好处是大大提高了代码的可维护性。

    其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。

    所以,模块一共三种:

    • python标准库
    • 第三方模块
    • 应用程序自定义模块

    另外,使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。

    #import mokuai
    # import mokuai# 引用模块下的mokuai里面的
    # # def run ():
    # #     print(mokuai.module(1,5))
    # # run() #6
    # def text ():
    #     print(mokuai.jianfa(1,5))
    # text()#-4
    # -------------------在mokuai里面定义的模块---------------
    # def module(x,y):
    #     return x+y
    # def jianfa(x,y):
    #     return x-y

    时间模块:

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

    • 时间戳(timestamp) :         通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
    • 格式化的时间字符串
    • 元组(struct_time)   :         struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
    #print(time.time())#时间戳从1970年凌晨开始算到现在经历多少秒
    #1481706107.8522012
    
    # t = time.localtime()
    # print(t)
    #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=14, tm_hour=17, tm_min=3, tm_sec=31, tm_wday=2, tm_yday=349, tm_isdst=0)
    #也可以取其中某一条
    # print(t.tm_mon)#12
    
    #print(time.gmtime())
    #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=14, tm_hour=9, tm_min=4, tm_sec=49, tm_wday=2, tm_yday=349, tm_isdst=0)
    #世界标准时间
    
    #将结构化时间转换成时间戳
    #print(time.mktime(time.localtime()))
    #1481706384.0
    
    #将结构化时间转换成字符串时间
    #print(time.strftime("%Y-%m-%d %X",time.localtime()))
    #2016-12-14 17:07:47 %X代表十分秒 格式可以自己定义
    
    #字符串时间转结构化时间
    #print(time.strptime("2016-12-14 17:07:47","%Y-%m-%d %X"))
    #time.struct_time(tm_year=2016, tm_mon=12, tm_mday=14, tm_hour=17, tm_min=7, tm_sec=47, tm_wday=2, tm_yday=349, tm_isdst=-1)
    
    #print(time.asctime())
    #Wed Dec 14 17:12:19 2016
    #print(time.ctime())
    #Wed Dec 14 17:12:40 2016
    #直接看时间
    
    #print(time.sleep(1))#推迟一秒运行时间 1代表1秒
    
    # import sys
    # time.sleep(1)
    # sys.stdout.write("#")
    # for i in range(10):
    #     sys.stdout.write("#")
    #     time.sleep(0.5)
    #     sys.stdout.flush()
    #每0.5秒输出一个#号

    sys模块:

    sys.argv           命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        退出程序,正常退出时exit(0)
    sys.version        获取Python解释程序的版本信息
    sys.maxint         最大的Int值
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称

    随机模块:

    # ret = random.random()
    # print(ret)
    #0.9228468894163326
    #出现0-1的随机浮点数
    
    #print(random.randint(1,6))
    #在1-6随机选取1个数
    
    #print(random.randrange(1,6))
    # 1-5 随机选取1个数
    
    #print(random.choice([11,22,33]))
    #随机选取一个
    
    #print(random.sample([11,22,33,44],2))
    #随机选取两个数
    
    #print(random.uniform(1,4))
    #随机选取1-4中的浮点数
    
    # ret = [1,2,3,4,5]
    # random.shuffle(ret)
    # print(ret)
    #[3, 2, 1, 4, 5]  打乱顺序
    
    # def v_code():
    #     ret = ""
    #     for i in range (4):
    #         num = random.randint(0,9)
    #         alf = chr(random.randint(65,122))
    #         s = str(random.choice([num,alf]))
    #         ret +=s
    #     return ret
    # v = (v_code())
    # print(v)
    #随机验证码

    os模块:

    os模块是与操作系统交互的一个接口

    os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
    os.curdir  返回当前目录: ('.')
    os.pardir  获取当前目录的父目录字符串名:('..')
    os.makedirs('dirname1/dirname2')    可生成多层递归目录
    os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()  删除一个文件
    os.rename("oldname","newname")  重命名文件/目录
    os.stat('path/filename')  获取文件/目录信息
    os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep    输出当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
    os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command")  运行shell命令,直接显示
    os.environ  获取系统环境变量
    os.path.abspath(path)  返回path规范化的绝对路径
    os.path.split(path)  将path分割成目录和文件名二元组返回
    os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
    os.path.basename(path)  返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
    os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
    os.path.isabs(path)  如果path是绝对路径,返回True
    os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
    os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

     json模块:

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

      如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

    序列化:

    我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

    序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

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

    import json
    #dic = {"name":"tom","age":23,}
    # print(type(dic)) #<class 'dict'>
    #j = json.dumps(dic)
    # print(type(j)) #<class 'str'>
    
    #f = open("jason","w")
    # f.write(j)==json.dumps(dic,f)
    # f.close()
    
    # f = open("jason",)
    # data = json.loads(f.read())#等价于data=json.load(f)
    import json
    #dct="{'1':111}"#json 不认单引号
    #dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}
    
    # dct='{"1":"111"}'
    # print(json.loads(dct))
    #conclusion:
    #无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

    pickle

    ##----------------------------序列化
    import pickle
     
    dic={'name':'alvin','age':23,'sex':'male'}
     
    print(type(dic))#<class 'dict'>
     
    j=pickle.dumps(dic)
    print(type(j))#<class 'bytes'>
     
     
    f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
    f.write(j)  #-------------------等价于pickle.dump(dic,f)
     
    f.close()
    #-------------------------反序列化
    import pickle
    f=open('序列化对象_pickle','rb')
     
    data=pickle.loads(f.read())#  等价于data=pickle.load(f)
     
     
    print(data['age'])   

      Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

    re模块:

      就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

     字符串模糊匹配

    元字符

    #.^$*+?
    #元字符
    #.通配符什么都能匹配 除了
    
    import re
    #print(re.findall("a..x","fafalexdasdas"))
    #['alex']点代表所有,.通配符什么都能匹配 除了
    
    #print(re.findall("^a..x","alexfafalexdasdas"))
    #^匹配a开头
    #print(re.findall("a..x$","alexfafalexdasdasalex"))
    #匹配$结尾
    #print(re.findall("d*","dddddddasfafdddd"))
    #['ddddddd', '', '', '', '', '', 'dddd', '']
    #*代表0 - 无穷次按最多的匹配
    #print(re.findall("d+","dddddddasfafdddd"))
    #['ddddddd', 'dddd']
    #+代表1 - 无穷次
    #print(re.findall("alex?","dadasalexxx"))
    #?最多只能有0 -1个
    #print(re.findall("alex?","dadasalexxx"))
    #可以自定义取范围,超出则为空
    
    #print(re.findall("x[y z]","xzuuuuu"))
    #['xz']或的意思  把z改成y的话结果就是xy,在里面没有特殊符号
    #这三个有意义- ^  /
    #print(re.findall("q[a-z]","qsdfsdf"))
    #['qs']
    #print(re.findall("q[a-z]*","qsdqqqqfsdf"))
    #['qsdqqqqfsdf'] 加*代表所有
     #- 代表a - z 从a到z
    #print(re.findall("q[^a-z]*","q234fff"))
    #['q234'] ^代表非得意思 就没有的意思
    
    #斜杠后面跟元字符去除特殊功能,比如.
    #斜杠后面跟普通字符实现特殊功能。比如d
    #d 匹配任何十进制数,相当于类[0-9]
    #D匹配任何非数字字符,相当于类[^0-9]
    #s匹配任何空白字符,相当于[	 
     
     f v]
    #S匹配任何非空白字符,相当于[^	 
     
     f v]
    #w 匹配任何数字字母字符,相当于[a-z A-Z 0-9]
    #W 匹配任何非数字字母字符,相当于[^a-z A-Z 0-9]
    #匹配一个特殊字符边界,比如空格 &,#等。
    #print(re.findall(r"ka|bc","sdakabcsf"))
    #['ka', 'bc'] ka和bc
    # v = re.search("d{2}","dsads34dasd15")
    # print(v.group()) #34
    #search 2代表2个在一起的数字 匹配第一个出现的
    # v = re.search("(?P<name>[a-z]+)(?P<age>d+)","alex36tom20jerry30")
    # print(v.group("name"))#alex
    # print(v.group("age"))#36
    #分组 如果没匹配到返回true
    
    # v = re.match("alex","alex36tom20jerry30")
    # print(v.group())
    #print(re.split(" ","hello abc def"))
    #['hello', 'abc', 'def']
    #print(re.split(" [ |]","hello abc|def"))
    #['hello abc|def']
    
    #print(re.split("[ab]","abcd"))
    #['', '', 'cd'] 先按a分,得到“”和bcd ,再对“”和bcd分别按b分割
    #print(re.sub("d","A","iop123iop123"))
    #iopAAAiopAAA  替换
    #print(re.sub("d","A","iop123iop123",3))
    #iopAAAiop123 匹配前3次
    #print(re.subn("d","A","iop123iop123",))
    #('iopAAAiopAAA', 6)告诉你匹配了几次
    
    #com = re.compile("d+")
    #print(com.findall("dad234ff"))
    #['234']  他可以自定义参数

    shelve模块:

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

    import shelve
     
    f = shelve.open(r'shelve.txt')
     
    # f['stu1_info']={'name':'alex','age':'18'}
    # f['stu2_info']={'name':'alvin','age':'20'}
    # f['school_info']={'website':'oldboyedu.com','city':'beijing'}
    #
    #
    # f.close()
     
    print(f.get('stu_info')['age'])

    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>
    View Code

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

    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
    print(root.tag)
     
    #遍历xml文档
    for child in root:
        print(child.tag, child.attrib)
        for i in child:
            print(i.tag,i.text)
     
    #只遍历year 节点
    for node in root.iter('year'):
        print(node.tag,node.text)
    #---------------------------------------
    
    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
     
    #修改
    for node in root.iter('year'):
        new_year = int(node.text) + 1
        node.text = str(new_year)
        node.set("updated","yes")
     
    tree.write("xmltest.xml")
     
     
    #删除node
    for country in root.findall('country'):
       rank = int(country.find('rank').text)
       if rank > 50:
         root.remove(country)
     
    tree.write('output.xml')
    View Code

    自己创建xml文档:

     1 import xml.etree.ElementTree 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) #打印生成的格式
    View Code

    configparser模块:

    来看一个好多软件的常见文档格式如下:

     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
    View Code

    用python:

    import configparser
      
    config = configparser.ConfigParser()
    config["DEFAULT"] = {'ServerAliveInterval': '45',
                          'Compression': 'yes',
                         'CompressionLevel': '9'}
      
    config['bitbucket.org'] = {}
    config['bitbucket.org']['User'] = 'hg'
    config['topsecret.server.com'] = {}
    topsecret = config['topsecret.server.com']
    topsecret['Host Port'] = '50022'     # mutates the parser
    topsecret['ForwardX11'] = 'no'  # same here
    config['DEFAULT']['ForwardX11'] = 'yes'<br>
    with open('example.ini', 'w') as configfile:
       config.write(configfile)
    View Code

    增删改查:

    import configparser
    
    config = configparser.ConfigParser()
    
    #---------------------------------------------查
    print(config.sections())   #[]
    
    config.read('example.ini')
    
    print(config.sections())   #['bitbucket.org', 'topsecret.server.com']
    
    print('bytebong.com' in config)# False
    
    print(config['bitbucket.org']['User']) # hg
    
    print(config['DEFAULT']['Compression']) #yes
    
    print(config['topsecret.server.com']['ForwardX11'])  #no
    
    
    for key in config['bitbucket.org']:
        print(key)
    
    
    # user
    # serveraliveinterval
    # compression
    # compressionlevel
    # forwardx11
    
    
    print(config.options('bitbucket.org'))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
    print(config.items('bitbucket.org'))  #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
    
    print(config.get('bitbucket.org','compression'))#yes
    
    
    #---------------------------------------------删,改,增(config.write(open('i.cfg', "w")))
    
    
    config.add_section('yuan')
    
    config.remove_section('topsecret.server.com')
    config.remove_option('bitbucket.org','user')
    
    config.set('bitbucket.org','k1','11111')
    
    config.write(open('i.cfg', "w"))
    View Code

    hashlib模块:

    用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

    import hashlib
     
    m=hashlib.md5()# m=hashlib.sha256()
     
    m.update('hello'.encode('utf8'))
    print(m.hexdigest())  #5d41402abc4b2a76b9719d911017c592
     
    m.update('alvin'.encode('utf8'))
     
    print(m.hexdigest())  #92a7e713c30abbb0319fa07da2a5c4af
     
    m2=hashlib.md5()
    m2.update('helloalvin'.encode('utf8'))
    print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
    View Code

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

    import hashlib
     
    # ######## 256 ########
     
    hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
    hash.update('alvin'.encode('utf8'))
    print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7

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

    import hmac
    h = hmac.new('alvin'.encode('utf8'))
    h.update('hello'.encode('utf8'))
    print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940

    subprocess模块:

      当我们需要调用系统的命令的时候,最先考虑的os模块。用os.system()和os.popen()来进行操作。但是这两个命令过于简单,不能完成一些复杂的操作,如给运行的命令提供输入或者读取命令的输出,判断该命令的运行状态,管理多个命令的并行等等。这时subprocess中的Popen命令就能有效的完成我们需要的操作。

          subprocess模块允许一个进程创建一个新的子进程,通过管道连接到子进程的stdin/stdout/stderr,获取子进程的返回值等操作。
    这个模块一个类open:
    #Popen它的构造函数如下:
     
    subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None,stderr=None, preexec_fn=None, close_fds=False, shell=False,<br>                 cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
    #参数args可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数。
    # 如果是序列类型,第一个元素通常是可执行文件的路径。我们也可以显式的使用executeable参
    # 数来指定可执行文件的路径。在windows操作系统上,Popen通过调用CreateProcess()来创
    # 建子进程,CreateProcess接收一个字符串参数,如果args是序列类型,系统将会通过
    # list2cmdline()函数将序列类型转换为字符串。
    # 
    # 
    # 参数bufsize:指定缓冲。我到现在还不清楚这个参数的具体含义,望各个大牛指点。
    # 
    # 参数executable用于指定可执行程序。一般情况下我们通过args参数来设置所要运行的程序。如
    # 果将参数shell设为True,executable将指定程序使用的shell。在windows平台下,默认的
    # shell由COMSPEC环境变量来指定。
    # 
    # 参数stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,
    # 文件描述符或文件对象,也可以设置为None,表示从父进程继承。
    # 
    # 参数preexec_fn只在Unix平台下有效,用于指定一个可执行对象(callable object),它将
    # 在子进程运行之前被调用。
    # 
    # 参数Close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会
    # 继承父进程的输入、输出、错误管道。我们不能将close_fds设置为True同时重定向子进程的标准
    # 输入、输出与错误(stdin, stdout, stderr)。
    # 
    # 如果参数shell设为true,程序将通过shell来执行。
    # 
    # 参数cwd用于设置子进程的当前目录。
    # 
    # 参数env是字典类型,用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父
    # 进程中继承。
    # 
    # 参数Universal_newlines:不同操作系统下,文本的换行符是不一样的。如:windows下
    # 用’/r/n’表示换,而Linux下用’/n’。如果将此参数设置为True,Python统一把这些换行符当
    # 作’/n’来处理。
    # 
    # 参数startupinfo与createionflags只在windows下用效,它们将被传递给底层的
    # CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等。
    View Code

    简单命令:

    import subprocess
     
    a=subprocess.Popen('ls')#  创建一个新的进程,与主进程不同步
     
    print('>>>>>>>',a)#a是Popen的一个实例对象
     
    '''
    >>>>>>> <subprocess.Popen object at 0x10185f860>
    __init__.py
    __pycache__
    log.py
    main.py
     
    '''
     
    # subprocess.Popen('ls -l',shell=True)
     
    # subprocess.Popen(['ls','-l'])

    logging模块:

    简单应用:

    import logging  
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')

    输出:

    WARNING:root:warning message
    ERROR:root:error message
    CRITICAL:root:critical message

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

    灵活配置日志级别,日志格式,输出位置:

    import logging  
    logging.basicConfig(level=logging.DEBUG,  
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                        datefmt='%a, %d %b %Y %H:%M:%S',  
                        filename='/tmp/test.log',  
                        filemode='w')  
      
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')

    查看输出:
    cat /tmp/test.log 
    Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL 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用户输出的消息

     
  • 相关阅读:
    scss 随机宽度函数
    github.com 连不了 Connection refused ssh.github.com port 443 22
    vscode tab size 缩进数设置 4 却总是自动重置为 2 的问题
    npm link 无效的原因?执行命令打开的是编辑器的问题?
    OpenCV图像特征提取与描述
    pandas对时间序列中缺失值进行线性插值
    图文解析:梯度下降原理与实现
    kindle dx 越狱 汉化 做电脑显示器 安装kindlePdfViewer 全搞定
    接口的幂等性如何设计?
    Spring大事务到底如何优化?
  • 原文地址:https://www.cnblogs.com/jasonenbo/p/6177975.html
Copyright © 2020-2023  润新知