zoukankan      html  css  js  c++  java
  • 模块补充

    一. sys三种流

    参考:‘’https://blog.csdn.net/qq_41654985/article/details/80396997"

    import sys
    sys.stdout.write('msg')
    sys.stderr.write('msg')
    msg = sys.stdin.readline()

    # print默认是对sys.stdout.write('msg') + sys.stdout.write(' ')的封装
    # 格式化结束符print:print('msg', end='')

    二.

    什么是XML

    全称叫做可扩展标记语言

    是一种定义电子文档结构和描述的语言,可以用来标记数据、定义数据类型

    用户可以对自己的标记语言进行定义和扩展,由W3C(万维网标准组织)推出,几乎所有的编程语言都支持该格式

    标记翻译为标签,标签指的是某种特殊符号,简单的是XML就是用标签来定义文档结构

    XML文档格式

    来看一个例子:

     <person name="jack">hello i am a person</person>

    一个完整的标签分为三个部分

    标签名(tagname): person

    属性(attribute): name 值为jack

    文本(text): hello i am a person

    属性和文本都是可选的,所以你可以这样来定义一个空标签

     <person></person>

    其他格式要求:

    一、任何的起始标签都必须有一个结束标签。

    二、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<person/>。XML解析器会将其翻译成<person></person>

    三、标签必须按顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。

    四、所有的属性都必须有值。

    五、所有的属性都必须在值的周围加上双引号。

    六、最外层必须有且只能有一个标签,称为根标签

    与JSON的对比

    json是JavaScript语言的对象表示法,其仅支持js中的数据类型,(虽然大多数情况下是足够使用的),之所以出现是因为在开发中,通常都需要后台向前台传输数据,那自然是要传输前台能看懂的数据格式,json就是这样一种数据格式,可以轻松的被js语言解析,使用场景多为前后台交互

    而xml支持的数据类型理论上是不受限制的,因为可以完全自定义标签的结构和含义,使用场景也非常广泛,不局限于前后台的数据交互,在一些语言中还经常作为配置文件来使用

    另外,HTML 看起来与XML非常的类似,的确,HTML也属于XML

    如果仅仅将XML用做数据交换格式的话,远不如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>

    解析XML

     import xml.etree.ElementTree as ET
     
     tree = ET.parse("xmltest.xml")
     root = tree.getroot()
     print(root.tag)
     
     #遍历xml文档
     for child in root:
         print('========>',child.tag,child.attrib,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')

    1.三个用于查找标签函数

     iter("标签名") #全文查找
     find("标签名") #查找子节点匹配的第一个
     findall("标签名") #查找字节点匹配的所有

    2.访问标签的内容

     element.tag 获取标签名
     element.attrib 获取属性
     element.text 获取文本

    3.修改文档内容

     elment.tag = "标签名"
     element.text = "文本"
     element.set("属性名","属性值")

    4.删除节点

     root.remove(标签对象)

    5.添加子标签

     #创建标签对象
     year2=ET.Element('year2') # 指定名称
     year2.text='新年'
     year2.attrib={'update':'yes'}
     #添加
     country.append(year2) #往country节点下添加子节点

    删除添加修改后都需要调用write写入到文件

     tree.write("文件名"),#注意文档对象才能执行写入操作

     

    代码生成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 = 'man'
     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的解析比起json而言非常复杂 因为其扩展性远比json高,在java中常作为配置文件,当你在前后台进行数据交互时,优先使用json格式

     三.shutil模块:

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

    1 import shutil
    2  
    3 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

    shutil.copyfile(src, dst)
    拷贝文件

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

    shutil.copymode(src, dst)
    仅拷贝权限。内容、组、用户均不变

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

    shutil.copystat(src, dst)
    仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

    1 shutil.copystat('f1.log', 'f2.log') #目标文件必须存在

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

    1 import shutil
    2  
    3 shutil.copy('f1.log', 'f2.log')

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

    1 import shutil
    2  
    3 shutil.copy2('f1.log', 'f2.log')

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

    import shutil
    2  
    3 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 
    import shutil
    
    shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    
    '''
    通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
    '''
    
    拷贝软连接

    shutil.rmtree(path[, ignore_errors[, onerror]])
    递归的去删除文件

    1 import shutil
    2  
    3 shutil.rmtree('folder1')

    shutil.move(src, dst)
    递归的去移动文件,它类似mv命令,其实就是重命名。

    1 import shutil
    2  
    3 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 两个模块来进行的,详细:

    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()
    
    zipfile压缩解压缩
    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()
    
    tarfile压缩解压缩

    四.shevle模块

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

    import shelve
    
    f=shelve.open(r'sheve.txt')
    # f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}
    # f['stu2_info']={'name':'gangdan','age':53}
    # f['school_info']={'website':'http://www.pypy.org','city':'beijing'}
    
    print(f['stu1_info']['hobby'])
    f.close()

    五.正则表达式

    什么是正则表达式

    一组特殊符号组成的表达式,用于描述某种规则。该应用场景生活中随处可见。

    例如:让有志青年过上体面的生活,这里面就由规则,即有志青年。

    正则表达式的作用,以及使用场景

    1.用于从字符串中匹配满足某种规则的内容,多数用于爬虫应用程序

    2.判断字符串串内容是否满足某种规则,多用于严重用户输入。例如密码是否规范,手机号是否正确等

    学习重点

    正则是一堆特殊符号组成的,我们主要学习的就是这些特殊符号

     

    元字符描述
    将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“n”匹配 。“ ”匹配换行符。序列“”匹配“”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
    ^ 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“ ”或“ ”之后的位置。
    $ 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“ ”或“ ”之前的位置。
    * 匹配前面的子表达式任意次。例如,zo能匹配“z”,也能匹配“zo”以及“zoo”。等价于{0,}。
    + 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
    {n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
    {n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
    {n,m} mn均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
    ? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。
    ? 当该字符紧跟在任何一个其他限制符(,+,?,{n},{n,},{n,m*})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']
    .点 匹配除“ ”和" "之外的任何单个字符。要匹配包括“ ”和" "在内的任何字符,请使用像“[sS]”的模式。
       
    x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[zf]ood”则匹配“zood”或“food”。
    [xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
    [^xyz] 负值字符集合。匹配未包含的任意字符。例如,“abc”可以匹配“plain”中的“plin”任一字符。
    [a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
    [^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“a-z”可以匹配任何不在“a”到“z”范围内的任意字符。
     匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的就是匹配位置的)。例如,“er”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“1”可以匹配“1_23”中的“1”,但不能匹配“21_3”中的“1_”。
    B 匹配非单词边界。“erB”能匹配“verb”中的“er”,但不能匹配“never”中的“er”
    s 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ f v]。
    S 匹配任何可见字符。等价于 f v
    w 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
    W 匹配任何非单词字符。等价于“A-Za-z0-9_”。
    d 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
    D 匹配一个非数字字符。等价于0-9。grep要加上-P,perl正则支持
    匹配一个换行符。等价于x0a和cJ。
    匹配一个回车符。等价于x0d和cM。
    匹配一个制表符。等价于x09和cI。
    ( ) 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 1 到9 的符号来引用。
    (?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
    | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。

    首先介绍的是re模块的findall方法,该方法用于从字符串中获取所有匹配成功的内容:

     import re
     res = re.findall("表达式""字符串内容")
     res = re.findall("w""hello python")
     res = re.findall("^http://""http://www.baidu.com http://www.sina.com.cn", re.M)
     # 该方法得到一个列表
     print(res)

    单个字符匹配

    w

    W

    s

    S

    d

    D

    .

    指定匹配范围

    a|b|c

    [abc]

    [^abc]

    [a-z]

    [a-zA-Z0-9]

    注意当 -需要作为普通字符时必须写在最前面或最后面

    匹配次数

    {a}

    {b,}

    {a,b}

    *

     

    位置匹配

    ^

    $

    d

    B

     

    贪婪模式

    默认情况下+和*将尽可能多的匹配内容

    +

    *

    非贪婪模式

    将尽可能少的匹配内容,当?出现在其他的重复次数后面时会将贪婪模式改为非贪婪模式。

    ?

    abc.*?

    abc.+?

     

    分组

    用于单独获取某一部分匹配的内容

    (表达式)获取匹配的

    (?:表达式) 不获取匹配的

    补充:

     #匹配模式:.不能匹配换行符
     content='''Hello 123456 World_This
     is a Regex Demo
     '''
     # res=re.match('He.*?(d+).*?Demo$',content)
     # print(res) #输出None
     
     # res=re.match('He.*?(d+).*?Demo$',content,re.S) #re.S让.可以匹配换行符
     # print(res)
     # print(res.group(1))

    re模块其他函数

    search

    仅获取第一个匹配的内容

    match

    从字符串开始处开始匹配

    compile

    得到一个的表达式对象,后期可以重复使用

    split

    使用正则表达式来切分字符串

     re.split("[:/\]","a:b/cd/f")

    sub

    普通替换与字符串的替换没有区别

    print(re.sub("python","PYTHON","python asasasaasa python"))

    正则替换 只替换后面的python

    print(re.sub("(python)(.*)(python)",r"12PYTHON","python asasasaasa python"))

  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/njzy-yuan/p/10690602.html
Copyright © 2011-2022 走看看