python笔记9-常用模块

sys模块

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%d%%' % (rate_num, ) #%% 表示一个%

    sys.stdout.write(r)

    sys.stdout.flush()

if __name__ == '__main__':

    for in range(1101):

        time.sleep(0.3)

        view_bar(i, 100)

time与datetime模块

在python中,通常3种时间的表示

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

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(13))  # [1,3]    大于等于1且小于等于3之间的整数

print(random.randrange(13))  # [1,3)    大于等于1且小于3之间的整数

print(random.choice([1'23', [45]]))  # 1或者23或者[4,5]

print(random.sample([1'23', [45]], 2))  # 列表元素任意2个组合

print(random.uniform(13))  # 大于1小于3的小数,如1.927109612082716

 

item = [13579]

random.shuffle(item)  # 打乱item的顺序,相当于"洗牌"

print(item)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

# 随机生成验证码

import random

def make_code(n):

    res = ''

    for in range(n):

        alf = chr(random.randint(6590))

        num = str(random.randint(09))

        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模块是与操作系统交互的一个接口

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的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

一、什么是序列化

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

二、为什么要序列化

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

三、什么是反序列化

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

  • 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如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'>

 

= json.dumps(dic)

print(type(j))  # <class 'str'>

 

= open('序列化对象''w')

f.write(j)  #等价于json.dump(dic,f)

f.close()

#反序列化

import json

= 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))

四、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'>

 

= pickle.dumps(dic)

print(type(j))  # <class 'bytes'>

 

= open('序列化对象_pickle''wb')  # 注意是w是写入str,wb是写入bytes,j是'bytes'

f.write(j)  #-等价于pickle.dump(dic,f)

 

f.close()

 

# 反序列化

import pickle

= open('序列化对象_pickle''rb')

data = pickle.loads(f.read())  # 等价于data=pickle.load(f)

print(data['age'])

shelve模块

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

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。

 

<?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>


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操作
class Element:
    """An XML element.

    This class is the reference implementation of the Element interface.

    An element's length is its number of subelements.  That means if you
    want to check if an element is truly empty, you should check BOTH
    its length AND its text attribute.

    The element tag, attribute names, and attribute values can be either
    bytes or strings.

    *tag* is the element name.  *attrib* is an optional dictionary containing
    element attributes. *extra* are additional element attributes given as
    keyword arguments.

    Example form:
        <tag attrib>text<child/>...</tag>tail

    """

    当前节点的标签名
    tag = None
    """The element's name."""

    当前节点的属性

    attrib = None
    """Dictionary of the element's attributes."""

    当前节点的内容
    text = None
    """
    Text before first subelement. This is either a string or the value None.
    Note that if there is no text, this attribute may be either
    None or the empty string, depending on the parser.

    """

    tail = None
    """
    Text after this element's end tag, but before the next sibling element's
    start tag.  This is either a string or the value None.  Note that if there
    was no text, this attribute may be either None or an empty string,
    depending on the parser.

    """

    def __init__(self, tag, attrib={}, **extra):
        if not isinstance(attrib, dict):
            raise TypeError("attrib must be dict, not %s" % (
                attrib.__class__.__name__,))
        attrib = attrib.copy()
        attrib.update(extra)
        self.tag = tag
        self.attrib = attrib
        self._children = []

    def __repr__(self):
        return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))

    def makeelement(self, tag, attrib):
        创建一个新节点
        """Create a new element with the same type.

        *tag* is a string containing the element name.
        *attrib* is a dictionary containing the element attributes.

        Do not call this method, use the SubElement factory function instead.

        """
        return self.__class__(tag, attrib)

    def copy(self):
        """Return copy of current element.

        This creates a shallow copy. Subelements will be shared with the
        original tree.

        """
        elem = self.makeelement(self.tag, self.attrib)
        elem.text = self.text
        elem.tail = self.tail
        elem[:] = self
        return elem

    def __len__(self):
        return len(self._children)

    def __bool__(self):
        warnings.warn(
            "The behavior of this method will change in future versions.  "
            "Use specific 'len(elem)' or 'elem is not None' test instead.",
            FutureWarning, stacklevel=2
            )
        return len(self._children) != 0 # emulate old behaviour, for now

    def __getitem__(self, index):
        return self._children[index]

    def __setitem__(self, index, element):
        # if isinstance(index, slice):
        #     for elt in element:
        #         assert iselement(elt)
        # else:
        #     assert iselement(element)
        self._children[index] = element

    def __delitem__(self, index):
        del self._children[index]

    def append(self, subelement):
        为当前节点追加一个子节点
        """Add *subelement* to the end of this element.

        The new element will appear in document order after the last existing
        subelement (or directly after the text, if it's the first subelement),
        but before the end tag for this element.

        """
        self._assert_is_element(subelement)
        self._children.append(subelement)

    def extend(self, elements):
        为当前节点扩展 n 个子节点
        """Append subelements from a sequence.

        *elements* is a sequence with zero or more elements.

        """
        for element in elements:
            self._assert_is_element(element)
        self._children.extend(elements)

    def insert(self, index, subelement):
        在当前节点的子节点中插入某个节点,即:为当前节点创建子节点,然后插入指定位置
        """Insert *subelement* at position *index*."""
        self._assert_is_element(subelement)
        self._children.insert(index, subelement)

    def _assert_is_element(self, e):
        # Need to refer to the actual Python implementation, not the
        # shadowing C implementation.
        if not isinstance(e, _Element_Py):
            raise TypeError('expected an Element, not %s' % type(e).__name__)

    def remove(self, subelement):
        在当前节点在子节点中删除某个节点
        """Remove matching subelement.

        Unlike the find methods, this method compares elements based on
        identity, NOT ON tag value or contents.  To remove subelements by
        other means, the easiest way is to use a list comprehension to
        select what elements to keep, and then use slice assignment to update
        the parent element.

        ValueError is raised if a matching element could not be found.

        """
        # assert iselement(element)
        self._children.remove(subelement)

    def getchildren(self):
        获取所有的子节点(废弃)
        """(Deprecated) Return all subelements.

        Elements are returned in document order.

        """
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'list(elem)' or iteration over elem instead.",
            DeprecationWarning, stacklevel=2
            )
        return self._children

    def find(self, path, namespaces=None):
        获取第一个寻找到的子节点
        """Find first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return the first matching element, or None if no element was found.

        """
        return ElementPath.find(self, path, namespaces)

    def findtext(self, path, default=None, namespaces=None):
        获取第一个寻找到的子节点的内容
        """Find text for first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *default* is the value to return if the element was not found,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return text content of first matching element, or default value if
        none was found.  Note that if an element is found having no text
        content, the empty string is returned.

        """
        return ElementPath.findtext(self, path, default, namespaces)

    def findall(self, path, namespaces=None):
        获取所有的子节点
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Returns list containing all matching elements in document order.

        """
        return ElementPath.findall(self, path, namespaces)

    def iterfind(self, path, namespaces=None):
        获取所有指定的节点,并创建一个迭代器(可以被for循环)
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return an iterable yielding all matching elements in document order.

        """
        return ElementPath.iterfind(self, path, namespaces)

    def clear(self):
        清空节点
        """Reset element.

        This function removes all subelements, clears all attributes, and sets
        the text and tail attributes to None.

        """
        self.attrib.clear()
        self._children = []
        self.text = self.tail = None

    def get(self, key, default=None):
        获取当前节点的属性值
        """Get element attribute.

        Equivalent to attrib.get, but some implementations may handle this a
        bit more efficiently.  *key* is what attribute to look for, and
        *default* is what to return if the attribute was not found.

        Returns a string containing the attribute value, or the default if
        attribute was not found.

        """
        return self.attrib.get(key, default)

    def set(self, key, value):
        为当前节点设置属性值
        """Set element attribute.

        Equivalent to attrib[key] = value, but some implementations may handle
        this a bit more efficiently.  *key* is what attribute to set, and
        *value* is the attribute value to set it to.

        """
        self.attrib[key] = value

    def keys(self):
        获取当前节点的所有属性的 key

        """Get list of attribute names.

        Names are returned in an arbitrary order, just like an ordinary
        Python dict.  Equivalent to attrib.keys()

        """
        return self.attrib.keys()

    def items(self):
        获取当前节点的所有属性值,每个属性都是一个键值对
        """Get element attributes as a sequence.

        The attributes are returned in arbitrary order.  Equivalent to
        attrib.items().

        Return a list of (name, value) tuples.

        """
        return self.attrib.items()

    def iter(self, tag=None):
        在当前节点的子孙中根据节点名称寻找所有指定的节点,并返回一个迭代器(可以被for循环)。
        """Create tree iterator.

        The iterator loops over the element and all subelements in document
        order, returning all elements with a matching tag.

        If the tree structure is modified during iteration, new or removed
        elements may or may not be included.  To get a stable set, use the
        list() function on the iterator, and loop over the resulting list.

        *tag* is what tags to look for (default is to return all elements)

        Return an iterator containing all the matching elements.

        """
        if tag == "*":
            tag = None
        if tag is None or self.tag == tag:
            yield self
        for e in self._children:
            yield from e.iter(tag)

    # compatibility
    def getiterator(self, tag=None):
        # Change for a DeprecationWarning in 1.4
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'elem.iter()' or 'list(elem.iter())' instead.",
            PendingDeprecationWarning, stacklevel=2
        )
        return list(self.iter(tag))

    def itertext(self):
        在当前节点的子孙中根据节点名称寻找所有指定的节点的内容,并返回一个迭代器(可以被for循环)。
        """Create text iterator.

        The iterator loops over the element and all subelements in document
        order, returning all inner text.

        """
        tag = self.tag
        if not isinstance(tag, str) and tag is not None:
            return
        if self.text:
            yield self.text
        for e in self:
            yield from e.itertext()
            if e.tail:
                yield e.tail

xml的语法功能

xml教程的:点击

configparser模块

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

 配置文件如下

# 注释1
; 注释2

[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31

[section2]
k1 = v1


配置文件如下

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值

一、hash值的特点是

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

1

2

3

4

5

6

7

8

9

10

11

12

'''

注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样

'''

import hashlib

= 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

二、添加自定义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 == cryptograph:

            print('密码是===>\033[46m%s\033[0m' %k)

 

cryptograph='f19b50d5e3433e65e6879d0e66632664'

break_code(cryptograph,make_passwd_dic(passwds))

三、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

= 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模块

高级的 文件、文件夹、压缩包 处理模块

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

# 压缩

= zipfile.ZipFile('laxi.zip''w')

z.write('a.log')

z.write('data.data')

z.close()

 

# 解压

= 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

2

3

4

5

6

CRITICAL = 50 #FATAL = CRITICAL

ERROR = 40

WARNING = 30 #WARN = WARNING

INFO = 20

DEBUG = 10

NOTSET = 0 #不设置

二、默认级别为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

'''

三、为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的配置

四、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

 

#1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出

logger=logging.getLogger(__file__)

 

#2、Filter对象:不常用,略

 

#3、Handler对象:接收logger传来的日志,然后控制输出

h1=logging.FileHandler('t1.log'#打印到文件

h2=logging.FileHandler('t2.log'#打印到文件

# h3=logging.StreamHandler() #打印到终端

 

#4、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',)

 

 

#5、为Handler对象绑定格式

h1.setFormatter(formmater1)

h2.setFormatter(formmater2)

# h3.setFormatter(formmater3)

 

#6、将Handler添加给logger并设置日志级别

logger.addHandler(h1)

logger.addHandler(h2)

# logger.addHandler(h3)

logger.setLevel(10)

 

#7、测试

logger.debug('debug')

logger.info('info')

logger.warning('warning')

logger.error('error')

logger.critical('critical')

五、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

"""

六、实例代码

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: 带有默认值的字典

一、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'])

二、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'])

三、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'

四、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'])

五、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})

Python学习笔记》是由皮大庆编写的一本关于Python语言学习的教材。在这本书中,作者详细介绍了Python语言的基础知识、语法规则以及常用的编程技巧。 首先,作者简要介绍了Python语言的特点和优势。他提到,Python是一种易于学习和使用的编程语言,受到了广大程序员的喜爱。Python具有简洁、清晰的语法结构,使得代码可读性极高,同时也提供了丰富的库和模块,能够快速实现各种功能。 接着,作者详细讲解了Python的基本语法。他从变量、数据类型、运算符等基础知识开始,逐步介绍了条件语句、循环控制、函数、模块等高级概念。同时,作者通过大量的示例代码和实践案例,帮助读者加深对Python编程的理解和应用。 在书中,作者还特别强调了编写规范和良好的编程习惯。他从命名规范、注释风格、代码缩进等方面指导读者如何写出清晰、可读性强的Python代码。作者认为,良好的编程习惯对于提高代码质量和提高工作效率非常重要。 此外,作者还介绍了Python常用库和模块。他提到了一些常用的库,如Numpy、Pandas、Matplotlib等。这些库在数据处理、科学计算、可视化等领域有广泛的应用,帮助读者更好地解决实际问题。 总的来说,《Python学习笔记》是一本非常实用和全面的Python学习教材。通过学习这本书,读者可以系统地学习和掌握Python编程的基础知识和高级应用技巧,为以后的编程学习和工作打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值