python经常使用模块

sys模块

sys模块是与 python解释器交互的一个接口javascript

?
1
2
3
4
5
6
7
8
9
import sys
sys.argv   #在命令行参数是一个空列表,在其余中第一个列表元素中程序自己的路径
sys.exit( 0 ) #退出程序,正常退出时exit(0)
sys.version  #获取python解释程序的版本信息
sys.path #返回模块的搜索路径,初始化时使用python PATH环境变量的值
sys.platform #返回操做系统平台的名称
sys.stdin    #输入相关
sys.stdout  #输出相关 
sys.stderror #错误相关
?
1
2
3
4
5
6
7
8
9
10
11
12
#模拟进度条
import sys,time
def view_bar(num, total):
     rate = float (num) / float (total)
     rate_num = int (rate * 100 )
     r = '\r%d%%' % (rate_num, ) #%% 表示一个%
     sys.stdout.write(r)
     sys.stdout.flush()
if __name__ = = '__main__' :
     for i in range ( 1 , 101 ):
         time.sleep( 0.3 )
         view_bar(i, 100 )

time与datetime模块

在python中,一般3种时间的表示html

  • 时间戳(timestamp):一般来讲,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。咱们运行“type(time.time())”,返回的是float类型。
  • 格式化的时间字符串(Format String)
  • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
%y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号自己
格式化时间的占位符

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import time
print (time.time())
# 时间戳:1546273960.5988934
 
print (time.localtime())
#本地时区的struct_time  time.struct_time(tm_year=2019, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=32, tm_sec=40, tm_wday=1, tm_yday=1, tm_isdst=0)
print (time.localtime( 1546273960.5988934 ))
#time.struct_time(tm_year=2019, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=32, tm_sec=40, tm_wday=1, tm_yday=1, tm_isdst=0)
 
print (time.gmtime())
#UTC时区的struct_time   time.struct_time(tm_year=2018, tm_mon=12, tm_mday=31, tm_hour=16, tm_min=32, tm_sec=40, tm_wday=0, tm_yday=365, tm_isdst=0)
print (time.gmtime( 1546273960.5988934 ))
#UTC时区的struct_time   time.struct_time(tm_year=2018, tm_mon=12, tm_mday=31, tm_hour=16, tm_min=32, tm_sec=40, tm_wday=0, tm_yday=365, tm_isdst=0)
 
print (time.mktime(time.localtime()))
#将一个结构化struct_time转化为时间戳。#1546274313.0
 
print (time.strftime( "%Y-%m-%d %X" ))
#格式化的时间字符串:'2019-01-01 00:32:40'
print (time.strftime( "%Y-%m-%d %X" , time.localtime()))
#格式化的时间字符串:'2019-01-01 00:32:40'
 
print (time.strptime( '2018-08-08 16:37:06' , '%Y-%m-%d %X' ))
#把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操做。 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=8, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=2, tm_yday=220, tm_isdst=-1)
 
time.sleep( 5 ) #线程推迟指定的时间运行,单位为秒。

?
1
2
3
4
5
6
import time
print (time.asctime()) #Tue Jan  1 00:53:00 2019
print (time.asctime(time.localtime())) #Tue Jan  1 00:55:00 2019
 
print (time.ctime())  # Tue Jan  1 00:53:00 2019
print (time.ctime(time.time()))  # Tue Jan  1 00:53:00 2019
?
1
2
3
4
5
6
7
8
9
10
11
12
13
#时间加减
import datetime,time
 
print (datetime.datetime.now()) #返回 2019-01-01 00:56:58.771296
print (datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2019-01-01
 
print (datetime.datetime.now() + datetime.timedelta( 3 )) #当前时间+3天  2019-01-04 00:56:58.771296
print (datetime.datetime.now() + datetime.timedelta( - 3 )) #当前时间-3天 2018-12-29 00:56:58.771296
print (datetime.datetime.now() + datetime.timedelta(hours = 3 )) #当前时间+3小时  2019-01-01 03:56:58.771296
print (datetime.datetime.now() + datetime.timedelta(minutes = 30 )) #当前时间+30分  2019-01-01 01:26:58.771296
 
c_time  = datetime.datetime.now()
print (c_time.replace(minute = 3 ,hour = 2 )) #时间替换  2019-01-01 02:03:58.771296

random模块

?
1
2
3
4
5
6
7
8
9
10
11
12
13
#随机生成
import random
 
print (random.random())  # (0,1)----float    大于0且小于1之间的小数
print (random.randint( 1 , 3 ))  # [1,3]    大于等于1且小于等于3之间的整数
print (random.randrange( 1 , 3 ))  # [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的小数,如1.927109612082716
 
item = [ 1 , 3 , 5 , 7 , 9 ]
random.shuffle(item)  # 打乱item的顺序,至关于"洗牌"
print (item)
# 随机生成验证码
import random
def make_code(n):
    res = ''
    for i in range(n):
        alf = chr(random.randint(65, 90))
        num = str(random.randint(0, 9))
        res += random.choice([alf, num])
    return res
print(make_code(6))

#########
import random, string
source = string.digits + string.ascii_lowercase + string.ascii_uppercase + string.ascii_letters
print(source)
#0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print("".join(random.sample(source, 6)))

os模块

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""
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下为"\t\n",Linux下为"\n"
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[, ...]])  将多个路径组合后返回,第一个绝对路径以前的参数将被忽略
print(os.path.join("D:\\python\\wwww","aaa"))   #作路径拼接用的 #D:\python\wwww\aaa
print(os.path.join(r"D:\python\wwww","aaa"))   #作路径拼接用的 #D:\python\wwww\aaa
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中全部字符转换为小写,并将全部斜杠转换为饭斜杠。
>>> os.path.normcase('c:/windows\\system32\\')  
'c:\\windows\\system32\\'  
    
 
规范化路径,如..和/
>>> os.path.normpath('c://windows\\System32\\../Temp/')  
'c:\\windows\\Temp'  
 
>>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..'
>>> print(os.path.normpath(a))
/Users/jieli/test1
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__))))
 
"""

json & pickle序列化模块

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

1、什么是序列化

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

2、为何要序列化

  • 持久保存状态
  • 跨平台数据交互

3、什么是反序列化

把变量内容从序列化的对象从新读到内存里称之为反序列化git

  • 若是咱们要在不一样的编程语言之间传递对象,就必须把对象序列化为标准格式,好比XML,但更好的方法是序列化为JSON,由于JSON表示出来就是一个字符串,能够被全部语言读取,也能够方便地存储到磁盘或者经过网络传输。
  • JSON不只是标准格式,而且比XML更快,并且能够直接在Web页面中读取,很是方便。
  • JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应以下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""
dumps,loads
"""
import json
 
dic = { 'name' : 'tom' , 'age' : 18 , '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)
 
 
"""
不管数据是怎样建立的,只要知足json格式,就能够json.loads出来,不必定非要dumps的数据才能loads
"""
import json
dct = "{'1':111}" #报错,json 不认单引号
dct = str ({ "1" : "111" }) #报错,由于生成的数据仍是单引号:{'1': '111'}
print (dct)  #{'1': '111'}
 
dct = str ( '{"1":"111"}' ) #正确写法
dct = '{"1":"111"}' #正确写法
print (json.loads(dct))

4、Pickle

Pickle的问题和全部其余编程语言特有的序列化问题同样,就是它只能用于Python,支持python全部的数据类型,有可能不一样版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的数据,不能成功地反序列化也不要紧。算法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pickle
dic = { 'name' : 'tom' , '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' ])

shelve模块

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

?
1
2
3
4
5
6
7
8
import shelve
f = shelve. open (r 'sheve.txt' )
#存
# f['stu1_info']={'name':'rose','age':18,'hobby':['sing','talk','swim']}
# f['stu2_info']={'name':'tom','age':53}
#取
print (f[ 'stu1_info' ][ 'hobby' ])
f.close()

xml模块

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

xmltest.xml
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
import xml.etree.ElementTree as ET
 
"""
############ 解析方式一 ############
str_xml = open('xmltest.xml', 'r').read()# 打开文件,读取XML内容
root = ET.XML(str_xml)# 将字符串解析成xml特殊对象,root代指xml文件的根节点
print(root.tag)#获取根节点的标签名
"""
############ 解析方式二 ############
tree = ET.parse("xmltest.xml")# 直接解析xml文件
root = tree.getroot()# 获取xml文件的根节点
print(root.tag)#获取根节点的标签名
 
# 遍历xml文档
for child in root:
    print('========>', child.tag, child.attrib, child.attrib['name'])
    for i in child:
        print(i.tag, i.attrib, 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')
    node.set('version', '1.0')
tree.write('test.xml')
 
# 删除node
for country in root.findall('country'):
    rank = int(country.find('rank').text)
    if rank > 50:
        root.remove(country)
 
tree.write('output.xml')
 
"""
#在country内添加(append)节点year2
"""
 
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.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')
 
 
"""
#本身建立xml文档
"""
 
import xml.etree.ElementTree as ET
 
new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age = ET.SubElement(name, "age", attrib={"checked": "no"})
sex = ET.SubElement(name, "sex")
sex.text = '33'
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = ET.SubElement(name2, "age")
age.text = '19'
 
et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True)
 
ET.dump(new_xml)  # 打印生成的格式
xml操做
  1 class Element:
  2     """An XML element.
  3 
  4     This class is the reference implementation of the Element interface.
  5 
  6     An element's length is its number of subelements.  That means if you
  7     want to check if an element is truly empty, you should check BOTH
  8     its length AND its text attribute.
  9 
 10     The element tag, attribute names, and attribute values can be either
 11     bytes or strings.
 12 
 13     *tag* is the element name.  *attrib* is an optional dictionary containing
 14     element attributes. *extra* are additional element attributes given as
 15     keyword arguments.
 16 
 17     Example form:
 18         <tag attrib>text<child/>...</tag>tail
 19 
 20     """
 21 
 22     当前节点的标签名
 23     tag = None
 24     """The element's name."""
 25 
 26     当前节点的属性
 27 
 28     attrib = None
 29     """Dictionary of the element's attributes."""
 30 
 31     当前节点的内容
 32     text = None
 33     """
 34     Text before first subelement. This is either a string or the value None.
 35     Note that if there is no text, this attribute may be either
 36     None or the empty string, depending on the parser.
 37 
 38     """
 39 
 40     tail = None
 41     """
 42     Text after this element's end tag, but before the next sibling element's
 43     start tag.  This is either a string or the value None.  Note that if there
 44     was no text, this attribute may be either None or an empty string,
 45     depending on the parser.
 46 
 47     """
 48 
 49     def __init__(self, tag, attrib={}, **extra):
 50         if not isinstance(attrib, dict):
 51             raise TypeError("attrib must be dict, not %s" % (
 52                 attrib.__class__.__name__,))
 53         attrib = attrib.copy()
 54         attrib.update(extra)
 55         self.tag = tag
 56         self.attrib = attrib
 57         self._children = []
 58 
 59     def __repr__(self):
 60         return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))
 61 
 62     def makeelement(self, tag, attrib):
 63         建立一个新节点
 64         """Create a new element with the same type.
 65 
 66         *tag* is a string containing the element name.
 67         *attrib* is a dictionary containing the element attributes.
 68 
 69         Do not call this method, use the SubElement factory function instead.
 70 
 71         """
 72         return self.__class__(tag, attrib)
 73 
 74     def copy(self):
 75         """Return copy of current element.
 76 
 77         This creates a shallow copy. Subelements will be shared with the
 78         original tree.
 79 
 80         """
 81         elem = self.makeelement(self.tag, self.attrib)
 82         elem.text = self.text
 83         elem.tail = self.tail
 84         elem[:] = self
 85         return elem
 86 
 87     def __len__(self):
 88         return len(self._children)
 89 
 90     def __bool__(self):
 91         warnings.warn(
 92             "The behavior of this method will change in future versions.  "
 93             "Use specific 'len(elem)' or 'elem is not None' test instead.",
 94             FutureWarning, stacklevel=2
 95             )
 96         return len(self._children) != 0 # emulate old behaviour, for now
 97 
 98     def __getitem__(self, index):
 99         return self._children[index]
100 
101     def __setitem__(self, index, element):
102         # if isinstance(index, slice):
103         #     for elt in element:
104         #         assert iselement(elt)
105         # else:
106         #     assert iselement(element)
107         self._children[index] = element
108 
109     def __delitem__(self, index):
110         del self._children[index]
111 
112     def append(self, subelement):
113         为当前节点追加一个子节点
114         """Add *subelement* to the end of this element.
115 
116         The new element will appear in document order after the last existing
117         subelement (or directly after the text, if it's the first subelement),
118         but before the end tag for this element.
119 
120         """
121         self._assert_is_element(subelement)
122         self._children.append(subelement)
123 
124     def extend(self, elements):
125         为当前节点扩展 n 个子节点
126         """Append subelements from a sequence.
127 
128         *elements* is a sequence with zero or more elements.
129 
130         """
131         for element in elements:
132             self._assert_is_element(element)
133         self._children.extend(elements)
134 
135     def insert(self, index, subelement):
136         在当前节点的子节点中插入某个节点,即:为当前节点建立子节点,而后插入指定位置
137         """Insert *subelement* at position *index*."""
138         self._assert_is_element(subelement)
139         self._children.insert(index, subelement)
140 
141     def _assert_is_element(self, e):
142         # Need to refer to the actual Python implementation, not the
143         # shadowing C implementation.
144         if not isinstance(e, _Element_Py):
145             raise TypeError('expected an Element, not %s' % type(e).__name__)
146 
147     def remove(self, subelement):
148         在当前节点在子节点中删除某个节点
149         """Remove matching subelement.
150 
151         Unlike the find methods, this method compares elements based on
152         identity, NOT ON tag value or contents.  To remove subelements by
153         other means, the easiest way is to use a list comprehension to
154         select what elements to keep, and then use slice assignment to update
155         the parent element.
156 
157         ValueError is raised if a matching element could not be found.
158 
159         """
160         # assert iselement(element)
161         self._children.remove(subelement)
162 
163     def getchildren(self):
164         获取全部的子节点(废弃)
165         """(Deprecated) Return all subelements.
166 
167         Elements are returned in document order.
168 
169         """
170         warnings.warn(
171             "This method will be removed in future versions.  "
172             "Use 'list(elem)' or iteration over elem instead.",
173             DeprecationWarning, stacklevel=2
174             )
175         return self._children
176 
177     def find(self, path, namespaces=None):
178         获取第一个寻找到的子节点
179         """Find first matching element by tag name or path.
180 
181         *path* is a string having either an element tag or an XPath,
182         *namespaces* is an optional mapping from namespace prefix to full name.
183 
184         Return the first matching element, or None if no element was found.
185 
186         """
187         return ElementPath.find(self, path, namespaces)
188 
189     def findtext(self, path, default=None, namespaces=None):
190         获取第一个寻找到的子节点的内容
191         """Find text for first matching element by tag name or path.
192 
193         *path* is a string having either an element tag or an XPath,
194         *default* is the value to return if the element was not found,
195         *namespaces* is an optional mapping from namespace prefix to full name.
196 
197         Return text content of first matching element, or default value if
198         none was found.  Note that if an element is found having no text
199         content, the empty string is returned.
200 
201         """
202         return ElementPath.findtext(self, path, default, namespaces)
203 
204     def findall(self, path, namespaces=None):
205         获取全部的子节点
206         """Find all matching subelements by tag name or path.
207 
208         *path* is a string having either an element tag or an XPath,
209         *namespaces* is an optional mapping from namespace prefix to full name.
210 
211         Returns list containing all matching elements in document order.
212 
213         """
214         return ElementPath.findall(self, path, namespaces)
215 
216     def iterfind(self, path, namespaces=None):
217         获取全部指定的节点,并建立一个迭代器(能够被for循环)
218         """Find all matching subelements by tag name or path.
219 
220         *path* is a string having either an element tag or an XPath,
221         *namespaces* is an optional mapping from namespace prefix to full name.
222 
223         Return an iterable yielding all matching elements in document order.
224 
225         """
226         return ElementPath.iterfind(self, path, namespaces)
227 
228     def clear(self):
229         清空节点
230         """Reset element.
231 
232         This function removes all subelements, clears all attributes, and sets
233         the text and tail attributes to None.
234 
235         """
236         self.attrib.clear()
237         self._children = []
238         self.text = self.tail = None
239 
240     def get(self, key, default=None):
241         获取当前节点的属性值
242         """Get element attribute.
243 
244         Equivalent to attrib.get, but some implementations may handle this a
245         bit more efficiently.  *key* is what attribute to look for, and
246         *default* is what to return if the attribute was not found.
247 
248         Returns a string containing the attribute value, or the default if
249         attribute was not found.
250 
251         """
252         return self.attrib.get(key, default)
253 
254     def set(self, key, value):
255         为当前节点设置属性值
256         """Set element attribute.
257 
258         Equivalent to attrib[key] = value, but some implementations may handle
259         this a bit more efficiently.  *key* is what attribute to set, and
260         *value* is the attribute value to set it to.
261 
262         """
263         self.attrib[key] = value
264 
265     def keys(self):
266         获取当前节点的全部属性的 key
267 
268         """Get list of attribute names.
269 
270         Names are returned in an arbitrary order, just like an ordinary
271         Python dict.  Equivalent to attrib.keys()
272 
273         """
274         return self.attrib.keys()
275 
276     def items(self):
277         获取当前节点的全部属性值,每一个属性都是一个键值对
278         """Get element attributes as a sequence.
279 
280         The attributes are returned in arbitrary order.  Equivalent to
281         attrib.items().
282 
283         Return a list of (name, value) tuples.
284 
285         """
286         return self.attrib.items()
287 
288     def iter(self, tag=None):
289         在当前节点的子孙中根据节点名称寻找全部指定的节点,并返回一个迭代器(能够被for循环)。
290         """Create tree iterator.
291 
292         The iterator loops over the element and all subelements in document
293         order, returning all elements with a matching tag.
294 
295         If the tree structure is modified during iteration, new or removed
296         elements may or may not be included.  To get a stable set, use the
297         list() function on the iterator, and loop over the resulting list.
298 
299         *tag* is what tags to look for (default is to return all elements)
300 
301         Return an iterator containing all the matching elements.
302 
303         """
304         if tag == "*":
305             tag = None
306         if tag is None or self.tag == tag:
307             yield self
308         for e in self._children:
309             yield from e.iter(tag)
310 
311     # compatibility
312     def getiterator(self, tag=None):
313         # Change for a DeprecationWarning in 1.4
314         warnings.warn(
315             "This method will be removed in future versions.  "
316             "Use 'elem.iter()' or 'list(elem.iter())' instead.",
317             PendingDeprecationWarning, stacklevel=2
318         )
319         return list(self.iter(tag))
320 
321     def itertext(self):
322         在当前节点的子孙中根据节点名称寻找全部指定的节点的内容,并返回一个迭代器(能够被for循环)。
323         """Create text iterator.
324 
325         The iterator loops over the element and all subelements in document
326         order, returning all inner text.
327 
328         """
329         tag = self.tag
330         if not isinstance(tag, str) and tag is not None:
331             return
332         if self.text:
333             yield self.text
334         for e in self:
335             yield from e.itertext()
336             if e.tail:
337                 yield e.tail
xml的语法功能

xml教程的:点击json

configparser模块

configparser用于处理特定格式的文件,本质上是利用open来操做文件,主要用于配置文件分析用的

该模块适用于配置文件的格式与windows ini文件相似,能够包含一个或多个节(section),每一个节能够有多个参数(键=值)。

配置文件以下
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"""
读取
"""
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
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"""
改写
"""
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' ))

  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
基于上述方法添加一个ini文档
"""
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)

hashlib模块

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

1、hash值的特色是

  • 只要传入的内容同样,获得的hash值必然同样
  • 不能由hash值返解成内容,不该该在网络传输明文密码
  • 只要使用的hash算法不变,不管校验的内容有多大,获得的hash值长度是固定的
?
1
2
3
4
5
6
7
8
9
10
11
12
'''
注意:把一段很长的数据update屡次,与一次update这段长数据,获得的结果同样
'''
import hashlib
m = hashlib.md5()  # m=hashlib.sha256()
m.update( 'hello' .encode( 'utf8' ))
print (m.hexdigest())  # 5d41402abc4b2a76b9719d911017c592
m.update( 'world' .encode( 'utf8' ))
print (m.hexdigest())  # fc5e038d38a57032085441e7fe7010b0
m2 = hashlib.md5()
m2.update( 'helloworld' .encode( 'utf8' ))
print (m2.hexdigest())  # fc5e038d38a57032085441e7fe7010b0

2、添加自定义key(加盐)

以上加密算法虽然依然很是厉害,但时候存在缺陷,即:经过撞库能够反解。因此,有必要对加密算法中添加自定义key再来作加密。

?
1
2
3
4
5
6
7
"""
对加密算法中添加自定义key再来作加密
"""
import hashlib
hash = hashlib.sha256( '898oaFs09f' .encode( 'utf8' ))
hash .update( 'alvin' .encode( 'utf8' ))
print ( hash .hexdigest())  # e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"""
模拟撞库破解密码
"""
import hashlib
passwds = [
     'tom3714' ,
     'tom1313' ,
     'tom94139413' ,
     'tom123456' ,
     '1234567890' ,
     'a123sdsdsa' ,
     ]
def make_passwd_dic(passwds):
     dic = {}
     for passwd in passwds:
         m = hashlib.md5()
         m.update(passwd.encode( 'utf-8' ))
         dic[passwd] = m.hexdigest()
     return dic
 
def break_code(cryptograph,passwd_dic):
     for k,v in passwd_dic.items():
         if v = = cryptograph:
             print ( '密码是===>\033[46m%s\033[0m' % k)
 
cryptograph = 'f19b50d5e3433e65e6879d0e66632664'
break_code(cryptograph,make_passwd_dic(passwds))

3、hmac模块

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import hmac
h = hmac.new( 'alvin' .encode( 'utf8' ))
h.update( 'hello' .encode( 'utf8' ))
print (h.hexdigest()) #320df9832eab4c038b6c1d7ed73a5940
 
"""
注意!注意!注意
#要想保证hmac最终结果一致,必须保证:
#1:hmac.new括号内指定的初始key同样
#2:不管update多少次,校验的内容累加到一块儿是同样的内容
"""
 
import hmac
 
h1 = hmac.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 'egonhelloworld' )
print (h3.hexdigest())
 
'''
f1bf38d054691688f89dcd34ac3c27f2
f1bf38d054691688f89dcd34ac3c27f2
bcca84edd9eeb86f30539922b28f3981
'''

shutil模块

shutil是一个高级的文件、文件夹、压缩包处理模块。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import shutil
"""
高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另外一个文件中
 
shutil.copyfile(src, dst)
拷贝文件,
 
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
 
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
 
shutil.copy(src, dst)
拷贝文件和权限
 
shutil.copy2(src, dst)
拷贝文件和状态信息
 
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
 
shutil.move(src, dst)
递归的去移动文件,它相似mv命令,其实就是重命名。
"""
 
shutil.copyfileobj( open ( 'xmltest.xml' , 'r' ), open ( 'new.xml' , 'w' ))
shutil.copyfile( 'b.txt' , 'bnew.txt' ) #目标文件无需存在
shutil.copymode( 'f1.log' , 'f2.log' ) #目标文件必须存在
shutil.copystat( 'f1.log' , 'f2.log' ) #目标文件必须存在
shutil.copy( 'f1.log' , 'f2.log' )
shutil.copy2( 'f1.log' , 'f2.log' )
shutil.copytree( 'folder1' , 'folder2' , ignore = shutil.ignore_patterns( '*.pyc' , 'tmp*' )) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
 
'''
一般的拷贝都把软链接拷贝成硬连接,即对待软链接来讲,建立新的文件
'''
#拷贝软链接
shutil.copytree( 'f1' , 'f2' , symlinks = True , ignore = shutil.ignore_patterns( '*.pyc' , 'tmp*' ))
 
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()

suprocess模块

suprocess模块的:官方文档

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import  subprocess
"""
Linux下:
"""
# obj = subprocess.Popen('ls', shell=True,
#                        stdout=subprocess.PIPE,
#                        stderr=subprocess.PIPE)
# stdout = obj.stdout.read()
# stderr = obj.stderr.read()
#
# #=========================
# res1=subprocess.Popen('ls',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 |grep txt$',shell=True,stdout=subprocess.PIPE)
# print(res1.stdout.read().decode('utf-8'))
 
"""
windows下:
# dir | findstr 'App*'
# dir | findstr 'App$'
"""
 
import subprocess
res1 = subprocess.Popen(r 'dir C:\Windows' ,shell = True ,stdout = subprocess.PIPE)
res = subprocess.Popen( 'findstr App*' ,shell = True ,stdin = res1.stdout,
                  stdout = subprocess.PIPE)
 
print (res.stdout.read().decode( 'gbk' )) #subprocess使用当前系统默认编码,获得结果为bytes类型,在windows下须要用gbk解码

logging模块

logging模块的:官方文档

Python的logging模块提供了通用的日志系统,能够方便第三方模块或者是应用使用。这个模块提供不一样的日志级别,并能够采用不一样的方式记录日志,好比文件,HTTP GET/POST,SMTP,Socket等,甚至能够本身实现具体的日志记录方式。

1、日志级别

?
1
2
3
4
5
6
CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
import logging
 
logging.debug( '调试debug' )
logging.info( '消息info' )
logging.warning( '警告warn' )
logging.error( '错误error' )
logging.critical( '严重critical' )
 
'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

3、为logging模块指定全局配置,针对全部logger有效,控制打印到文件中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"""
可在logging.basicConfig()函数中可经过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名建立FiledHandler,这样日志会被存储在指定的文件中。
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用户输出的消息
"""
#========使用
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' )
 
# #========结果
# access.log内容:
# 2019-01-14 18:53:32 PM - root - DEBUG -1:  调试debug
# 2019-01-14 18:53:32 PM - root - INFO -1:  消息info
# 2019-01-14 18:53:32 PM - root - WARNING -1:  警告warn
# 2019-01-14 18:53:32 PM - root - ERROR -1:  错误error
# 2019-01-14 18:53:32 PM - root - CRITICAL -1:  严重critical
 
# part2: 能够为logging模块指定模块级的配置,即全部logger的配置

4、logging模块的Formatter,Handler,Logger,Filter对象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
"""
logger:产生日志的对象
Filter:过滤日志的对象
Handler:接收日志而后控制打印到不一样的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
Formatter对象:能够定制不一样的日志格式对象,而后绑定给不一样的Handler对象使用,以此来控制不一样的Handler的日志格式
"""
import logging
 
#一、logger对象:负责产生日志,而后交给Filter过滤,而后交给不一样的Handler输出
logger = logging.getLogger(__file__)
 
#二、Filter对象:不经常使用,略
 
#三、Handler对象:接收logger传来的日志,而后控制输出
h1 = logging.FileHandler( 't1.log' ) #打印到文件
h2 = logging.FileHandler( 't2.log' ) #打印到文件
# h3=logging.StreamHandler() #打印到终端
 
#四、Formatter对象:日志格式
formmater1 = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s' ,
                     datefmt = '%Y-%m-%d %H:%M:%S %p' ,)
 
formmater2 = logging.Formatter( '%(asctime)s :  %(message)s' ,
                     datefmt = '%Y-%m-%d %H:%M:%S %p' ,)
 
formmater3 = logging.Formatter( '%(name)s %(message)s' ,)
 
 
#五、为Handler对象绑定格式
h1.setFormatter(formmater1)
h2.setFormatter(formmater2)
# h3.setFormatter(formmater3)
 
#六、将Handler添加给logger并设置日志级别
logger.addHandler(h1)
logger.addHandler(h2)
# logger.addHandler(h3)
logger.setLevel( 10 )
 
#七、测试
logger.debug( 'debug' )
logger.info( 'info' )
logger.warning( 'warning' )
logger.error( 'error' )
logger.critical( 'critical' )

5、Logger与Handler的级别(logger是第一级过滤,而后才能到handler)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 )
 
log1 = logging.getLogger( 'root' )
# log1.setLevel(20)
log1.setLevel( 40 )
log1.addHandler(ch)
 
log1.debug( 'log1 debug' )
log1.info( 'log1 info' )
log1.warning( 'log1 warning' )
log1.error( 'log1 error' )
log1.critical( 'log1 critical' )
 
"""
logger是第一级过滤,而后才能到handler
 
2019-01-14 19:43:04 PM - root - ERROR -1:  log1 error
2019-01-14 19:43:04 PM - root - CRITICAL -1:  log1 critical
"""

6、实例代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#core/logger.py
import os
import logging
from conf import settings
 
def logger(log_type):
 
     logger = logging.getLogger(log_type)
     logger.setLevel(settings.LOG_LEVEL)
 
     ch = logging.StreamHandler()  #屏幕
     ch.setLevel(settings.LOG_LEVEL)
 
     log_dir = "%s/log" % (settings.BASE_DIR)
     if not os.path.exists(log_dir):
         os.makedirs(log_dir)
     log_file = "%s/log/%s" % (settings.BASE_DIR, settings.LOG_TYPES[log_type])
     fh = logging.FileHandler(log_file)  #文件
     fh.setLevel(settings.LOG_LEVEL)
 
     formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
 
     ch.setFormatter(formatter)
     fh.setFormatter(formatter)
 
     logger.addHandler(ch)
     logger.addHandler(fh)
 
     return logger
 
#core/main.py  调用
from core import logger
trans_logger = logger.logger( 'transaction' )
access_logger = logger.logger( 'access' )
 
def run():
     trans_logger.debug( 'trans_logger debug' )
     trans_logger.info( 'trans_logger info' )
     trans_logger.warning( 'trans_logger warning' )
     trans_logger.error( 'trans_logger error' )
     trans_logger.critical( 'trans_logger critical' )
 
     access_logger.debug( 'access_logger debug' )
     access_logger.info( 'access_logger info' )
     access_logger.warning( 'access_logger warning' )
     access_logger.error( 'access_logger error' )
     access_logger.critical( 'access_logger critical' )
run()
 
#conf/setting.py
import os
import logging
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
LOG_LEVEL = logging.INFO
LOG_TYPES = {
     'transaction' : 'transactions.log' ,
     'access' : 'access.log' ,
}

collections模块

collections模块在内置数据类型(dict、list、set、tuple)的基础上,还提供了几个额外的数据类型:ChainMap、Counter、deque、defaultdict、namedtuple和OrderedDict等。

  • namedtuple: 生成可使用名字来访问元素内容的tuple子类
  • deque: 双端队列,能够快速的从另一侧追加和推出对象
  • Counter: 计数器,主要用来计数
  • OrderedDict: 有序字典
  • defaultdict: 带有默认值的字典

1、namedtuple

  • namedtuple是一个函数,它用来建立一个自定义的tuple对象,而且规定了tuple元素的个数,并能够用属性而不是索引来引用tuple的某个元素。
  • 它具有tuple的不变性,又能够根据属性来引用,使用十分方便。
?
1
2
3
4
5
6
from collections import namedtuple
Point = namedtuple( 'Point' , [ 'x' , 'y' ])
p = Point( 1 , 2 ) #表示坐标   t = (1, 2)很难看出这个tuple是用来表示一个坐标的。
print (p.x, isinstance (p,Point), isinstance (p, tuple ))  # 1 True True  验证建立的Point对象是tuple的一种子类
#若是要用坐标和半径表示一个圆,也能够用namedtuple定义:
Circle = namedtuple( 'Circle' , [ 'x' , 'y' , 'r' ])

2、deque

  • 使用list存储数据时,按索引访问元素很快,可是插入和删除元素就很慢了,由于list是线性存储,数据量大的时候,插入和删除效率很低。
  • deque是为了高效实现插入和删除操做的双向列表,适合用于队列和栈
  • deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就能够很是高效地往头部添加或删除元素。
?
1
2
3
4
5
from collections import deque
q = deque([ 'a' , 'b' , 'c' ])
q.append( 'x' )
q.appendleft( 'y' )
print (q) # deque(['y', 'a', 'b', 'c', 'x'])

3、defaultdict

  • 使用dict时,若是引用的Key不存在,就会抛出KeyError。若是但愿key不存在时,返回一个默认值,就能够用defaultdict
  • 注意默认值是调用函数返回的,而函数在建立defaultdict对象时传入。
  • 除了在Key不存在时返回默认值,defaultdict的其余行为跟dict是彻底同样的。
?
1
2
3
4
5
from collections import defaultdict
dd = defaultdict( lambda : 'N/A' )
dd[ 'key1' ] = 'abc'
print (dd[ 'key1' ]) # key1存在 'abc'
print (dd[ 'key2' ]) # key2不存在,返回默认值 'N/A'

4、OrderedDict

  • 使用dict时,Key是无序的。在对dict作迭代时,咱们没法肯定Key的顺序。若是要保持Key的顺序,能够用OrderedDict
  • 注意,OrderedDict的Key会按照插入的顺序排列,不是Key自己排序
  • OrderedDict能够实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最先添加的Key
?
1
2
3
4
5
6
7
8
9
10
11
12
13
from collections import OrderedDict
d = dict ([( 'a' , 1 ), ( 'b' , 2 ), ( 'c' , 3 )])
print (d) # dict的Key是无序的  {'a': 1, 'c': 3, 'b': 2}
#保持Key的顺序
od = OrderedDict([( 'a' , 1 ), ( 'b' , 2 ), ( 'c' , 3 )])
print (od) # OrderedDict的Key是有序的  OrderedDict([('a', 1), ('b', 2), ('c', 3)])
 
#OrderedDict的Key会按照插入的顺序排列,不是Key自己排序:
od = OrderedDict()
od[ 'z' ] = 1
od[ 'y' ] = 2
od[ 'x' ] = 3
print (od.keys()) # 按照插入的Key的顺序返回 odict_keys(['z', 'y', 'x'])

5、Counter

  • Counter是一个简单的计数器,例如,统计字符出现的个数
  • Counter实际上也是dict的一个子类,上面的结果能够看出,字符'g'、'm'、'r'各出现了两次,其余字符各出现了一次。
?
1
2
3
4
5
from collections import Counter
c = Counter()
for ch in 'programming' :
     c[ch] = c[ch] + 1
print (c) #Counter({'r': 2, 'm': 2, 'g': 2, 'p': 1, 'n': 1, 'a': 1, 'i': 1, 'o': 1})
import configparser

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

# print(config._sections)
"""
OrderedDict([('section1', OrderedDict(
    [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')])),
             ('section2', OrderedDict([('k1', 'v1')]))])
"""

# print(dict(config._sections))

"""
{'section2': OrderedDict([('k1', 'v1')]), 'section1': OrderedDict(
    [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')])}
"""

# print(dict(('k1', 'v1')))  # {'v': '1', 'k': '1'}
# print(dict([('k1', 'v1')]))  # {'k1': 'v1'}
# print(dict(['k1', 'v1']))  # {'v': '1', 'k': '1'}

d = dict(config._sections)

for k in d:
    # print(d[k])
    """
    OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')])
    OrderedDict([('k1', 'v1')])
    """
    # print(dict(d[k]))
    '''
    {'age': '18', 'user': 'egon', 'k2': 'v2', 'salary': '31', 'is_admin': 'true', 'k1': 'v1'}
    {'k1': 'v1'}
    '''
    d[k] = dict(d[k])

# print(d)
'''
{'section2': {'k1': 'v1'},
 'section1': {'user': 'egon', 'is_admin': 'true', 'k2': 'v2', 'salary': '31', 'age': '18', 'k1': 'v1'}}
'''

class MyParser(configparser.ConfigParser):
    def as_dict(self):
        """
        讲configparser.ConfigParser().read()读取到的数据转成dict类型返回
        :return:
        """
        d = dict(self._sections)
        for k in d:
            d[k] = dict(d[k])
        return d

cfg = MyParser()
cfg.read('a.cfg',encoding='utf8')
print(cfg.as_dict())
View Code
相关文章
相关标签/搜索