zoukankan      html  css  js  c++  java
  • Python-14-常用模块

    一、time&datatime

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

    • 时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
    • 格式化的时间字符串
    • 元组(struct_time)   :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

    1. time模块

    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中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行
    # 时间,即两次时间差。
    

     

    2. datetime模块

    #时间加减
    import datetime
    
    # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
    #print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
    # print(datetime.datetime.now() )
    # print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
    # print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
    # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
    # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
    
    
    #
    # c_time  = datetime.datetime.now()
    # print(c_time.replace(minute=3,hour=2)) #时间替换
    
    datetime模块
    

    二、random模块

    import random
     
    print(random.random())#(0,1)----float
     
    print(random.randint(1,3))  #[1,3]
     
    print(random.randrange(1,3)) #[1,3)
     
    print(random.choice([1,'23',[4,5]]))#23
     
    print(random.sample([1,'23',[4,5]],2))#[[4, 5], '23']
     
    print(random.uniform(1,3))#1.927109612082716
     
     
    item=[1,3,5,7,9]
    random.shuffle(item)
    print(item)
    

     三、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所指向的文件或者目录的最后修改时间
    
    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模块

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

     五、json&pickle

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

    import json
    x="[null,true,false,1]"
    print(eval(x)) #报错,无法解析null类型,而json就可以
    print(json.loads(x)) 
    

    1. 什么是序列化?

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

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

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

    2. json模块

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

    JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

    #----------------------------序列化
    import json
     
    dic={'name':'alvin','age':23,'sex':'male'}
    print(type(dic))#<class 'dict'>
     
    j=json.dumps(dic)
    print(type(j))#<class 'str'>
     
     
    f=open('序列化对象','w')
    f.write(j)  # 等价于json.dump(dic,f)
    f.close()
    #-----------------------------反序列化
    import json
    f=open('序列化对象')
    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
    注意

    3. pickle模块

    pickle模块的用法与json相同,但转化的不是字符串类型,而是bytes类型。

    Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用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()
    
    # -------------------------反序列化
    f = open('序列化对象_pickle', 'rb')
    data = pickle.loads(f.read())  # 等价于data=pickle.load(f)
    print(data['age'])
    

    六、shelve模块

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

    import shelve
    
    f = shelve.open(r'shelve.txt')  # 将一个字典放入文本 f = {}
    f['stu1'] = 'Tom'
    f['stu2'] = {'name': 'gangdan', 'age': 53}
    f['school_info'] = {'website': 'http://www.pypy.org', 'city': 'beijing'}
    
    print(f['stu1'])
    print(f['stu2']['name'])
    f.close()
    

    七、xml模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

     1 import xml.etree.ElementTree as ET
     2 
     3 tree = ET.parse("xml")
     4 root = tree.getroot()
     5 
     6 # xml遍历
     7 for i in root:
     8     # print(i.tag)
     9     # print(i.attrib)
    10     for j in i:
    11         print(j.tag)  # 标签
    12         print(j.attrib)  # 属性
    13         print(j.text)  # 文本
    14 
    15 # 只遍历year节点
    16 for node in root.iter('year'):
    17     print(node.tag, node.text)
    18 # year 2008
    19 # year 2011
    20 # year 2011
    21 
    22 # 修改
    23 for node in root.iter('year'):
    24     # 修改文本
    25     new_year = int(node.text) + 1
    26     node.text = str(new_year)
    27     # 修改属性
    28     node.set('updated', 'yes')
    29 # 写入修改
    30 tree.write('new.xml')
    31 
    32 # 在country内添加(append)节点year2
    33 for country in root.findall('country'):
    34     for year in country.findall('year'):
    35         if int(year.text) > 2000:
    36             year2 = ET.Element('year2')
    37             year2.text = '新年'
    38             year2.attrib = {'update': 'yes'}
    39             country.append(year2)  # 往country节点下添加子节点
    40 
    41 tree.write('a.xml.swap')
    42 
    43 # 删除
    44 for country in root.findall('country'):
    45     rank = int(country.find('rank').text)
    46     if rank > 50:
    47         root.remove(country)
    48 tree.write('new.xml')
    常用操作
     1 # 创建xml文件
     2 import xml.etree.ElementTree as ET
     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)  # 打印生成的格式
    创建xml

    八、re模块

    1. 什么是正则表达式

    正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

    2. 字符匹配

    • 普通字符:大多数字符和字母都会和自身匹配

    • 元字符:. ^ $ * + ? { } [ ] | ( )

    import re
    
    # w与W
    print(re.findall('w', 'hello egon 123'))  # ['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    print(re.findall('W', 'hello egon 123'))  # [' ', ' ']
    
    # s与S
    print(re.findall('s', 'hello  egon  123'))  # [' ', ' ', ' ', ' ']
    print(re.findall('S', 'hello  egon  123'))  # ['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    # 
     	都是空,都可以被s匹配
    print(re.findall('s', 'hello 
     egon 	 123'))  # [' ', '
    ', ' ', ' ', '	', ' ']
    
    # 
    与	
    print(re.findall(r'
    ', 'hello egon 
    123'))  # ['
    ']
    print(re.findall(r'	', 'hello egon	123'))  # ['
    ']
    
    # d与D
    print(re.findall('d', 'hello egon 123'))  # ['1', '2', '3']
    print(re.findall('D', 'hello egon 123'))  # ['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']
    
    # A与
    print(re.findall('Ahe', 'hello egon 123'))  # ['he'],A==>^
    print(re.findall('123', 'hello egon 123'))  # ['he'],==>$
    
    # ^与$
    print(re.findall('^h', 'hello egon 123'))  # ['h']
    print(re.findall('3$', 'hello egon 123'))  # ['3']
    
    # .
    print(re.findall('a.b', 'a1b'))  # ['a1b']
    print(re.findall('a.b', 'a1b a*b a b aaab'))  # ['a1b', 'a*b', 'a b', 'aab']
    print(re.findall('a.b', 'a
    b'))  # []
    print(re.findall('a.b', 'a
    b', re.S))  # ['a
    b']
    print(re.findall('a.b', 'a
    b', re.DOTALL))  # ['a
    b']同上一条意思一样
    
    # 重复匹配:| * | ? | .* | .*? | + | {n,m} |
    
    # *  
    print(re.findall('ab*', 'bbbbbbb'))  # []
    print(re.findall('ab*', 'a'))  # ['a']
    print(re.findall('ab*', 'abbbb'))  # ['abbbb']
    
    # ?
    print(re.findall('ab?', 'a'))  # ['a']
    print(re.findall('ab?', 'abbb'))  # ['ab']
    # 匹配所有包含小数在内的数字
    print(re.findall('d+.?d*', "asdfasdf123as1.13dfa12adsf1asdf3"))  # ['123', '1.13', '12', '1', '3']
    
    # .*默认为贪婪匹配
    print(re.findall('a.*b', 'a1b22222222b'))  # ['a1b22222222b']
    
    # .*?为非贪婪匹配:推荐使用
    print(re.findall('a.*?b', 'a1b22222222b'))  # ['a1b']
    
    # +
    print(re.findall('ab+', 'a'))  # []
    print(re.findall('ab+', 'abbb'))  # ['abbb']
    
    # {n,m}
    print(re.findall('ab{2}', 'abbb'))  # ['abb']
    print(re.findall('ab{2,4}', 'abbb'))  # ['abb']
    print(re.findall('ab{1,}', 'abbb'))  # 'ab{1,}' ===> 'ab+'
    print(re.findall('ab{0,}', 'abbb'))  # 'ab{0,}' ===> 'ab*'
    
    #字符集[]
    ret=re.findall('a[bc]d','acd')
    print(ret)#['acd']
     
    ret=re.findall('[a-z]','acd')
    print(ret)#['a', 'c', 'd']
     
    ret=re.findall('[.*+]','a.cd+')
    print(ret)#['.', '+']
     
    #在字符集里有功能的符号: - ^ 
     
    ret=re.findall('[1-9]','45dha3')
    print(ret)#['4', '5', '3']
     
    ret=re.findall('[^ab]','45bdha3')
    print(ret)#['4', '5', 'd', 'h', '3']
     
    ret=re.findall('[d]','45bdha3')
    print(ret)#['4', '5', '3']
    
    # # print(re.findall('a\c','ac')) #对于正则来说a\c确实可以匹配到ac,但是在python解释器读取a\c时,会发生转义,然后交给re去执行,所以抛出异常
    print(re.findall(r'a\c', 'ac'))  # r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
    print(re.findall('a\\c', 'ac'))  # 同上面的意思一样,和上面的结果一样都是['a\c']
    
    # ():分组
    print(re.findall('ab+', 'ababab123'))  # ['ab', 'ab', 'ab']
    print(re.findall('(ab)+123', 'ababab123'))  # ['ab'],匹配到末尾的ab123中的ab
    print(re.findall('(?:ab)+123', 'ababab123'))  # findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
    print(re.findall('href="(.*?)"', '<a href="http://www.baidu.com">点击</a>'))  # ['http://www.baidu.com']
    print(re.findall('href="(?:.*?)"', '<a href="http://www.baidu.com">点击</a>'))  # ['href="http://www.baidu.com"']
    
    # |
    print(re.findall('compan(?:y|ies)', 'Too many companies have gone bankrupt, and the next one is my company'))
    
    import re
    
    print(re.findall("<(?P<tag_name>w+)>w+</(?P=tag_name)>", "<h1>hello</h1>"))
    print(re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>", "<h1>hello</h1>"))
    print(re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>", "<h1>hello</h1>").group('tag_name'))
    print(re.search(r"<(w+)>w+</1>", "<h1>hello</h1>"))
    # ['h1']
    # <re.Match object; span=(0, 14), match='<h1>hello</h1>'>
    # h1
    # <re.Match object; span=(0, 14), match='<h1>hello</h1>'>
    
    #匹配出所有的整数
    import re
    
    #ret=re.findall(r"d+{0}]","1-2*(60+(-40.35/5)-(-4*3))")
    ret=re.findall(r"-?d+.d*|(-?d+)","1-2*(60+(-40.35/5)-(-4*3))")
    ret.remove("")
    
    print(ret)
    

    3. 常用方法

    import re
    #1
    re.findall('a','alvin yuan')    #返回所有满足匹配条件的结果,放在列表里
    #2
    re.search('a','alvin yuan').group()  #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
                                         # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
     
    #3
    re.match('a','abc').group()     #同search,不过尽在字符串开始处进行匹配
     
    #4
    ret=re.split('[ab]','abcd')     #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
    print(ret)#['', '', 'cd']
     
    #5
    ret=re.sub('d','abc','alvin5yuan6',1)
    print(ret)#alvinabcyuan6
    ret=re.subn('d','abc','alvin5yuan6')
    print(ret)#('alvinabcyuanabc', 2)
     
    #6
    obj=re.compile('d{3}')
    ret=obj.search('abc123eeee')
    print(ret.group())#123
    1
    2
    3
    4
    5
    6
    	
    import re
    ret=re.finditer('d','ds3sy4784a')
    print(ret)        #<callable_iterator object at 0x10195f940>
     
    print(next(ret).group())
    print(next(ret).group())
    

    九、logging模块

    1. 日志级别

    CRITICAL = 50 #FATAL = CRITICAL

    ERROR = 40

    WARNING = 30 #WARN = WARNING

    INFO = 20

    DEBUG = 10

    NOTSET = 0 #不设置

    默认只会打印出warning以上级别的信息

    2. 基础配置

    import logging
    
    logging.basicConfig(  # 基础设置
        level=logging.DEBUG,  # 设置rootlogger的日志级别
        filename='logger.log',  # 用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中
        filemode='w',  # 文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
        format='%(asctime)s %(filename)s [%(lineno)d] %(message)s'  # 指定handler使用的日志显示格式。
        # stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。
        # 若同时列出了filename和stream两个参数,则stream参数会被忽略。
    )
    logging.debug('kjhk')
    logging.error('nhdvh')
    
    # 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:用户输出的消息
    

    3. logging模块的Formatter,Handler,Logger,Filter对象

    def log():
        # logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
        logger = logging.getLogger('mylogger')
        # Filter对象:不常用,略
        # Handler对象:接收logger传来的日志,然后控制输出
        fh = logging.FileHandler('log_test')  # 打印到文件
        ch = logging.StreamHandler()  # 打印到终端
        # Formatter对象:日志格式
        fm = logging.Formatter('%(asctime)s %(filename)s [%(lineno)d] %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p')
        # 为Handler对象绑定格式
        fh.setFormatter(fm)
        ch.setFormatter(fm)
        # 将Handler添加给logger并设置日志级别
        logger.addHandler(fh)
        logger.addHandler(ch)
        logger.setLevel('DEBUG')
        return logger
    
    
    # 测试
    logger = log()
    logger.info('hello')
    logging.debug('kjhk')
    logging.error('nhdvh')
    logging.warning('sg')
    logging.critical('sv')
    

    4. logger的继承

    import logging
    
    formatter = 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(formatter)
    
    logger1 = logging.getLogger('root')
    logger2 = logging.getLogger('root.child1')
    logger3 = logging.getLogger('root.child1.child2')
    
    logger1.addHandler(ch)
    logger2.addHandler(ch)
    logger3.addHandler(ch)
    logger1.setLevel(10)
    logger2.setLevel(10)
    logger3.setLevel(10)
    
    logger1.debug('log1 debug')
    logger2.debug('log2 debug')
    logger3.debug('log3 debug')
    '''
    2017-07-28 22:22:05 PM - root - DEBUG -test:  log1 debug
    2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
    2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
    2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    '''
    

    十、configparser模块

    configparser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section), 每个节可以有多个参数(键=值)。

    1. 配置文件样式

    # 注释1
    ; 注释2
    
    [section1]
    k1 = v1
    k2:v2
    user=egon
    age=18
    is_admin=true
    salary=31
    
    [section2]
    k1 = v1

    2. 创建

    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'
    with open('example.ini', 'w') as configfile:
       config.write(configfile)
    

    3. 读取

    import configparser
    
    config = configparser.ConfigParser()
    config.read('confile')
    
    # 查看所有的标题
    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
    

    4. 修改

    import configparser
    
    config = configparser.ConfigParser()
    config.read('confile', 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', 'user'))
    
    # 添加一个标题
    config.add_section('egon')
    
    # 在标题egon下添加name=egon,age=18的配置
    config.set('egon', 'name', 'egon')
    config.set('egon', 'age', 18)  # 报错,必须是字符串
    
    # 最后将修改的内容写入文件,完成最终的修改
    config.write(open('confile', 'w'))
    
    

    十一、hashlib模块

    1. 什么是hash

    hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值。

    2. hash值的特点

    • 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验
    • 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码
    • 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的

    3. 使用

    import hashlib
    
    ha = hashlib.sha256()
    ha.update('hello'.encode('utf-8'))
    print(ha.hexdigest())
    
    m = hashlib.sha256('sb'.encode('utf-8'))
    m.update('hello'.encode('utf-8'))
    print(ha.hexdigest())
    

    十二、subprocess模块

    import  subprocess
    
    '''
    sh-3.2# ls /Users/egon/Desktop |grep txt$
    mysql.txt
    tt.txt
    事物.txt
    '''
    
    res1=subprocess.Popen('ls /Users/jieli/Desktop',shell=True,stdout=subprocess.PIPE)
    res=subprocess.Popen('grep txt$',shell=True,stdin=res1.stdout,
                     stdout=subprocess.PIPE)
    
    print(res.stdout.read().decode('utf-8'))
    
    
    #等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
    res1=subprocess.Popen('ls /Users/jieli/Desktop |grep txt$',shell=True,stdout=subprocess.PIPE)
    print(res1.stdout.read().decode('utf-8'))
    
    
    #windows下:
    # dir | findstr 'test*'
    # dir | findstr 'txt$'
    import subprocess
    res1=subprocess.Popen(r'dir C:UsersAdministratorPycharmProjects	est函数备课',shell=True,stdout=subprocess.PIPE)
    res=subprocess.Popen('findstr test*',shell=True,stdin=res1.stdout,
                     stdout=subprocess.PIPE)
    
    print(res.stdout.read().decode('gbk')) #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
    
  • 相关阅读:
    Android AHandle AMessage
    android java 与C 通过 JNI双向通信
    android 系统给应用的jar
    UE4 unreliable 同步问题
    UE4 difference between servertravel and openlevel(多人游戏的关卡切换)
    UE4 Run On owing Client解析(RPC测试)
    UE4 TSubclassOf VS Native Pointer
    UE4 内容示例网络同步Learn
    UE4 多人FPS VR游戏制作笔记
    UE4 分层材质 Layerd Materials
  • 原文地址:https://www.cnblogs.com/lsf123456/p/11181384.html
Copyright © 2011-2022 走看看