• python day7


    一、configparser 模块
    用于处理特定格式的文件,其本质上是利用open来操作文件。


    示例文件
    [section1]          # 节点
    k1 = v1             # 值
    k2:v2                # 值
     
    [section2]          # 节点
    k1 = v1             # 值

    测试,获得aa文件的特定格式信息
    文件 aa
    [section1]
    k1 = v1
    k2 = v2

    [section2]
    k1 = v1 


    1、获取所有节点
    import configparser

    config = configparser.ConfigParser()
    config.read('aa', encoding='utf-8')                 #读aa文件
    ret = config.sections()                                 #获取并形成格式
    print(ret)

    结果
    ['section1', 'section2']


    2、获取指定节点下所有的键值对
    import configparser

    config = configparser.ConfigParser()
    config.read('aa', encoding='utf-8')
    ret = config.items('section1')                    #使用items获取section1节点键值对
    print(ret)

    结果
    [('k2', 'v2'), ('k10', '123')]


    3、获取指定节点下所有的建

    import configparser

    config = configparser.ConfigParser()
    config.read('aa', encoding='utf-8')
    ret = config.options('section1')                #使用options获取section1的key
    print(ret)


    结果
    ['k1', 'k2']

    4、获取指定节点下指定key的值

    import configparser

    config = configparser.ConfigParser()
    config.read('aa', encoding='utf-8')
    v = config.get('section1', 'k1')                    #使用get获取section1键k1的值
    # v = config.getint('section1', 'k1')
    # v = config.getfloat('section1', 'k1')
    # v = config.getboolean('section1', 'k1')
    print(v)


    结果
    v1  

    5、检查、删除、添加节点

    import configparser

    config = configparser.ConfigParser()
    config.read('aa', encoding='utf-8')

    # 检查
    has_sec = config.has_section('section1')
    print(has_sec)

    # 添加节点
    config.add_section("SEC_1")
    config.write(open('aa', 'w'))

    # 删除节点
    config.remove_section("SEC_1")
    config.write(open('aa', 'w'))

    结果:
    True

    6、检查、删除、设置指定组内的键值对

    import configparser

    config = configparser.ConfigParser()                            #必须有
    config.read('aa', encoding='utf-8')                              #必须有

    # 检查
    has_opt = config.has_option('section1', 'k1')                #检查节点对应的key是否存在,存在True,不存在False
    print(has_opt)

    # 删除
    config.read('aa', encoding='utf-8')
    config.remove_option('section1','k1')                           #删除section1节的k1键值对
    config.write(open('aa','w'))

    # 设置
    config.set('section1', 'k10', "123")                            #有则修改,无则添加
    config.write(open('aa', 'w'))

    二、XML


    浏览器返回的字符串
        a.    HTML
        b.    json
        c.    XML
            页面上做展示(字符串类型的一个xml格式数据)
            配置文件(文件,内部数据xml格式)
           
    XML是实现不同语言或程序之间进行数据交换的协议,XML文件格式如下:

    xo.xml

    <data>                                          #<data>为根  (名自定义)
        <country name="Liechtenstein">              #<country为节点,后面跟属性>
            <rank updated="yes">2</rank>                                            
            <year>2023</year>                                                      
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year>2026</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year>2026</year>
            <gdppc>13600</gdppc>
            <neighbor direction="W" name="Costa Rica" />
            <neighbor direction="E" name="Colombia" />
        </country>
    </data>

    1.解析xml
    使用ElementTree
    xo.xml

    <data1 title="CTO" age="19">
        <country name="Liechtenstein" age="18">
            <rank updated="yes">2</rank>
            <year>2023</year>
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year>2026</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year>2026</year>
            <gdppc>13600</gdppc>
            <neighbor direction="W" name="Costa Rica" />
            <neighbor direction="E" name="Colombia" />
        </country>

    </data1>

    -----test.py脚本
    利用ElementTree.parse将文件直接解析成xml对象
    from xml.etree import ElementTree as ET

    tree = ET.parse('xo.xml')                                 
    root = tree.getroot()                                       #获取xml根
    print(root.tag,' ')


    for child in root:
        print(child.tag,child.attrib)                     #获取节点字符,属性
        for gradechild in child:
            print(gradechild.tag, gradechild.text)        #获取节点名,节点内容


    结果:
    <Element 'data1' at 0x00000000006B71D8>


    country {'age': '18', 'name': 'Liechtenstein'}
    rank 2
    year 2023
    gdppc 141100
    neighbor None
    neighbor None
    country {'name': 'Singapore'}
    rank 5
    year 2026
    gdppc 59900
    neighbor None
    country {'name': 'Panama'}
    rank 69
    year 2026
    gdppc 13600
    neighbor None
    neighbor None

    2.操作XML

    两种操作xml方式
        解析字符串方式打开,删除,保存
            将字符串解析成xml特殊对象 ET.XML(str_xml),用open        
        解析文件方式打开,删除,保存        
            直接解析xml文件  ET.parse("xo.xml"),不用open(程序内容实现)
           
           
    示例xml
    <data1 title="CTO" age="19">
        <country name="Liechtenstein" age="18">
            <rank updated="yes">2</rank>                                        #内容为2
            <year>2023</year>
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>                                         #内容为5
            <year>2026</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>                                       #内容为69
            <year>2026</year>
            <gdppc>13600</gdppc>
            <neighbor direction="W" name="Costa Rica" />
            <neighbor direction="E" name="Colombia" />
        </country>

    ET.XML方法---用open
    ET.parse方法---不用open
        由于 每个节点 都具有以上的方法,并且在上一步骤中解析时均得到了root(xml文件的根节点),so   可以利用以上方法进行操作xml文件。

    a. 遍历XML文档的所有内容

    from xml.etree import ElementTree as ET

    #解析方式一   ET.XML方法---用open
    """
    str_xml = open('xo.xml', 'r').read()    # 打开文件,读取XML内容
    root = ET.XML(str_xml)                  # 将字符串解析成xml特殊对象,root代指xml文件的根节点
    """
    #解析方式二  ET.parse方法---不用open
    tree = ET.parse("xo.xml")               # 直接解析xml文件
    root = tree.getroot()                   # 获取xml文件的根节点
    #操作
    print(root.tag)                         # 顶层标签
    for child in root:                      # 遍历XML文档的第二层
        print(child.tag, child.attrib)      # 第二层节点的标签名称和标签属性
        for i in child:                     # 遍历XML文档的第三层
            print(i.tag,i.text)             # 第二层节点的标签名称和内容

    结果
    data1
    country {'name': 'Liechtenstein', 'age': '18'}
    rank 2
    year 2023
    gdppc 141100
    neighbor None
    neighbor None
    country {'name': 'Singapore'}
    rank 5
    year 2026
    gdppc 59900
    neighbor None
    country {'name': 'Panama'}
    rank 69
    year 2026
    gdppc 13600
    neighbor None
    neighbor None


    b、遍历XML中指定的节点

    from xml.etree import ElementTree as ET

    #解析方式一   ET.XML方法---用open
    """
    str_xml = open('xo.xml', 'r').read()    # 打开文件,读取XML内容
    root = ET.XML(str_xml)                  # 将字符串解析成xml特殊对象,root代指xml文件的根节点
    """
    #解析方式二  ET.parse方法---不用open
    tree = ET.parse("xo.xml")               # 直接解析xml文件
    root = tree.getroot()                   # 获取xml文件的根节点
    #操作
    print(root.tag)                         # 顶层标签
    for node in root.iter('year'):          # 遍历XML中所有的year节点
        print(node.tag, node.text)          # 节点的标签名称和内容


    结果
    data1
    year 2023
    year 2026
    year 2026

    c、修改节点内容

    由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。

    (1) ET.XML方法--用open
    from xml.etree import ElementTree as ET

    #解析方式一  ET.XML方法--用open
    str_xml = open('xo.xml', 'r').read()                    # 打开文件,读取XML内容
    root = ET.XML(str_xml)                                  # 将字符串解析成xml特殊对象,root代指xml文件的根节点
    #操作
    print(root.tag)                                         # 顶层标签
    for node in root.iter('year'):                          # 循环所有的year节点
        new_year = int(node.text) + 1                       # 将year节点中的内容自增一
        node.text = str(new_year)
        node.set('name', 'alex')                            # 设置属性,添加name属性信息
        node.set('age', '18')
        del node.attrib['name']                             # 删除属性,与year相匹配的name,即上面的name为alex的属性
    #保存文件
    tree = ET.ElementTree(root)
    tree.write("newnew.xml", encoding='utf-8')


    (2) ET.parse方法---不用open-
    from xml.etree import ElementTree as ET

    #解析方式二
    tree = ET.parse("xo.xml")                               # 直接解析xml文件
    root = tree.getroot()                                   # 获取xml文件的根节点
    #操作
    print(root.tag)                                         # 顶层标签
    for node in root.iter('year'):                          # 循环所有的year节点
        new_year = int(node.text) + 1                       # 将year节点中的内容自增一
        node.text = str(new_year)
        node.set('name', 'alex')                            # 设置属性,添加name属性信息
        node.set('age', '18')
        del node.attrib['name']                             # 删除属性,与year相匹配的name,即上面的name为alex的属性
    #保存文件
    tree.write("newnew.xml", encoding='utf-8')

    结果
    <data1 age="19" title="CTO">
        <country age="18" name="Liechtenstein">
            <rank updated="yes">2</rank>
            <year age="18">2024</year>
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year age="18">2027</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year age="18">2027</year>
            <gdppc>13600</gdppc>
            <neighbor direction="W" name="Costa Rica" />
            <neighbor direction="E" name="Colombia" />
        </country>
       

    d、删除节点

    功能:实现删除rank节点内容大于50的内容,并将修改后内容写入新文件
    (1) ET.XML方法--用open---解析字符串方式打开,删除,保存
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang
    from xml.etree import ElementTree as ET

    #解析字符串方式打开
    str_xml = open('xo.xml', 'r').read()        # 打开文件,读取XML内容
    root = ET.XML(str_xml)                      # 将字符串解析成xml特殊对象,root代指xml文件的根节点
    #操作
    print(root.tag)                             # 顶层标签
    for country in root.findall('country'):     # 遍历data下的所有country节点
        rank = int(country.find('rank').text)   # 获取每一个country节点下rank节点的内容
        if rank > 50:                           # 内容数字大于50的删除
            root.remove(country)                # 删除指定country节点
    #保存文件
    tree = ET.ElementTree(root)
    tree.write("newnew.xml", encoding='utf-8')  # 写入到新文件


    (2) ET.parse方法---不用open--解析文件方式打开,删除,保存 
    from xml.etree import ElementTree as ET

    #解析文件方式
    tree = ET.parse("xo.xml")                   # 直接解析xml文件
    root = tree.getroot()                       # 获取xml文件的根节点
    #操作
    print(root.tag)                             # 顶层标签
    for country in root.findall('country'):     # 遍历data下的所有country节点
        rank = int(country.find('rank').text)   # 获取每一个country节点下rank节点的内容
        if rank > 50:     
            root.remove(country)                # 删除指定country节点
    #保存文件
    tree.write("newnew.xml", encoding='utf-8')

    结果
    ---新生成文件newnew.xml发现没有69对应内容,代表操作成功
    <data1 age="19" title="CTO">
        <country age="18" name="Liechtenstein">
            <rank updated="yes">2</rank>                            #内容为2
            <year>2023</year>
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>                            #内容为5
            <year>2026</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        </data1>


    3、创建XML文档

    (1) 以一行形式写入

    from xml.etree import ElementTree as ET
    root = ET.Element("famliy")                                 # 创建根节点
    son1 = ET.Element('son', {'name': '儿1'})                   # 创建节点大儿子
    son2 = ET.Element('son', {"name": '儿2'})                   # 创建小儿子
    grandson1 = ET.Element('grandson', {'name': '儿11'})        # 在大儿子中创建两个孙子
    grandson2 = ET.Element('grandson', {'name': '儿12'})
    son1.append(grandson1)
    son1.append(grandson2)
    root.append(son1)                                          # 把儿子添加到根节点中
    root.append(son1)
    tree = ET.ElementTree(root)
    tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)


    结果
    <famliy><son name="儿1"><grandson name="儿11"></grandson><grandson name="儿12"></grandson></son><son name="儿1"><grandson name="儿11"></grandson><grandson name="儿12"></grandson></son></famliy>
     

    (2) 方式二
    from xml.etree import ElementTree as ET
    root = ET.Element("famliy")                                 # 创建根节点
    # son1 = ET.Element('son', {'name': '儿1'})                 # 创建大儿子
    son1 = root.makeelement('son', {'name': '儿1'})
    # son2 = ET.Element('son', {"name": '儿2'})
    son2 = root.makeelement('son', {"name": '儿2'})             # 创建小儿子
    # grandson1 = ET.Element('grandson', {'name': '儿11'})      # 在大儿子中创建两个孙子
    grandson1 = son1.makeelement('grandson', {'name': '儿11'})
    # grandson2 = ET.Element('grandson', {'name': '儿12'})
    grandson2 = son1.makeelement('grandson', {'name': '儿12'})
    son1.append(grandson1)
    son1.append(grandson2)
    root.append(son1)                                          # 把儿子添加到根节点中
    root.append(son1)
    tree = ET.ElementTree(root)
    tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)


    结果
    <famliy><son name="儿1"><grandson name="儿11"></grandson><grandson name="儿12"></grandson></son><son name="儿1"><grandson name="儿11"></grandson><grandson name="儿12"></grandson></son></famliy>
     
    (3) 方式三
    from xml.etree import ElementTree as ET
    root = ET.Element("famliy")                                          # 创建根节点
    son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})            # 创建节点大儿子
    son2 = ET.SubElement(root, "son", attrib={"name": "儿2"})            # 创建小儿子
    grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})      # 在大儿子中创建一个孙子  #Sub创建节点,并append,干了两件事
    grandson1.text = '孙子'
    et = ET.ElementTree(root)                                            #生成文档对象
    et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)

    结果
    <?xml version='1.0' encoding='utf-8'?>
    <famliy><son name="儿1"><age name="儿11">孙子</age></son><son name="儿2"></son></famliy>

    由于原生保存的XML时默认无缩进,如果想要设置缩进的话, 需要修改保存方式:
    from xml.etree import ElementTree as ET
    from xml.dom import minidom

    def prettify(elem):
        """将节点转换成字符串,并添加缩进。
        """
        rough_string = ET.tostring(elem, 'utf-8')         #换字符串
        reparsed = minidom.parseString(rough_string)      #格式化
        return reparsed.toprettyxml(indent=" ")          #加 制表符

    root = ET.Element("famliy")                           # 创建根节点
    # 创建大儿子
    # son1 = ET.Element('son', {'name': '儿1'})
    son1 = root.makeelement('son', {'name': '儿1'})
    # 创建小儿子
    # son2 = ET.Element('son', {"name": '儿2'})
    son2 = root.makeelement('son', {"name": '儿2'})
    # 在大儿子中创建两个孙子
    # grandson1 = ET.Element('grandson', {'name': '儿11'})
    grandson1 = son1.makeelement('grandson', {'name': '儿11'})
    # grandson2 = ET.Element('grandson', {'name': '儿12'})
    grandson2 = son1.makeelement('grandson', {'name': '儿12'})
    son1.append(grandson1)
    son1.append(grandson2)
    # 把儿子添加到根节点中
    root.append(son1)
    root.append(son1)
    raw_str = prettify(root)
    f = open("xxxoo.xml",'w',encoding='utf-8')
    f.write(raw_str)
    f.close()

    结果
    <?xml version="1.0" ?>
    <famliy>
        <son name="儿1">
            <grandson name="儿11"/>
            <grandson name="儿12"/>
        </son>
        <son name="儿1">
            <grandson name="儿11"/>
            <grandson name="儿12"/>
        </son>
    </famliy>

    4、命名空间
    from xml.etree import ElementTree as ET

    ET.register_namespace('com',"http://www.company.com") #some name

    # build a tree structure
    root = ET.Element("{http://www.company.com}STUFF")
    body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF", attrib={"{http://www.company.com}hhh": "123"})
    body.text = "STUFF EVERYWHERE!"

    # wrap it in an ElementTree instance, and save as XML
    tree = ET.ElementTree(root)

    tree.write("page.xml",
               xml_declaration=True,
               encoding='utf-8',
               method="xml")

    结果
    <?xml version='1.0' encoding='utf-8'?>
    <com:STUFF xmlns:com="http://www.company.com"><com:MORE_STUFF com:hhh="123">STUFF EVERYWHERE!</com:MORE_STUFF></com:STUFF>


    三、系统命令

    可以执行shell命令的相关模块和函数有:
        os.system
        os.spawn*
        os.popen*          --废弃
        popen2.*           --废弃
        commands.*      --废弃,3.x中被移除
       
    import commands

    result = commands.getoutput('cmd')
    result = commands.getstatus('cmd')
    result = commands.getstatusoutput('cmd')


    call
    执行命令,返回状态码
    import subprocess
    ret = subprocess.call(["ls", "-l"], shell=False)     #False 返回列表
    ret = subprocess.call("ls -l", shell=True)           #True 返回字符

    check_call
    执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
    subprocess.check_call(["ls", "-l"])
    subprocess.check_call("exit 1", shell=True)


    check_output
    执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
    import subprocess
    subprocess.check_output(["echo", "Hello World!"])
    subprocess.check_output("exit 1", shell=True)


    subprocess.Popen(...)

    用于执行复杂的系统命令

    参数:
    args:shell命令,可以是字符串或者序列类型(如:list,元组)
    bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
    stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
    preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
    close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
    所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
    shell:同上
    cwd:用于设置子进程的当前目录
    env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
    universal_newlines:不同系统的换行符不同,True -> 同意使用 ?startupinfo与createionflags只在windows下有效
    将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等


    创建目录
    import subprocess
    ret1 = subprocess.Popen(["mkdir","t1"])
    ret2 = subprocess.Popen("mkdir t2", shell=True)

    删除目录
    import subprocess
    ret1 = subprocess.Popen(["rm",'-rf',"t1"])
    ret2 = subprocess.Popen("rm -rf t2", shell=True)

    终端输入的命令分为两种:
        输入即可得到输出,如:ifconfig
        输入进行某环境,依赖再输入,如:python

    在指的定目录操作(建目录)
    import subprocess
    obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)

    在系统中执行python进入交互模式,输入信息
    import subprocess
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    obj.stdin.write("print(1) ")
    obj.stdin.write("print(2)")
    obj.stdin.close()

    cmd_out = obj.stdout.read()
    obj.stdout.close()
    cmd_error = obj.stderr.read()
    obj.stderr.close()

    print(cmd_out)
    print(cmd_error)

    输出错误行
    import subprocess

    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    obj.stdin.write("print(1) ")
    obj.stdin.write("print(2)")

    out_error_list = obj.communicate()
    print(out_error_list)

    import subprocess

    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    out_error_list = obj.communicate('print("hello")')
    print(out_error_list)

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

    1. shutil 使用
    import shutil
    shutil.copyfileobj
    shutil.copyfileobj(fsrc, fdst[, length])

    # 将文件内容拷贝到另一个文件中
    # 一个目拷贝
    import shutil
    shutil.copyfileobj(open('xo.xml','r'), open('new.xml', 'w'))
    shutil.copyfile()

    # copy 内容
    import shutil
    shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

    #copy 文件
    shutil.copyfile(src,dst)
    shutil.copyfile('xo.xml','aa.xml')


    # 拷贝文件
    shutil.copyfile('f1.log', 'f2.log')


    # 仅拷贝权限。内容、组、用户均不变(目标文件必须存在)
    -rwxrwxrwx. 1 root root   110 6月  23 21:55 a.py         #文件 a.py    777权限
    -rw-r--r--. 1 root root   892 5月  10 22:57 ug.py        #文件 ug.py   644权限
    shutil.copymode('a.py', 'ug.py')

    结果
    -rwxrwxrwx. 1 root root   892 5月  10 22:57 ug.py       #ug.py 变777,但内容没变


    # 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
    shutil.copystat('f1.log', 'f2.log')

    # 拷贝文件和权限
    import shutil
    shutil.copy('f1.log', 'f2.log')
      
      

    # 拷贝文件和状态信息
    import shutil
    shutil.copy2('f1.log', 'f2.log')

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

    import shutil
    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

    import shutil
    shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))


    # 递归的去删除文件
    import shutil
    shutil.rmtree('folder1')

    # 递归的去移动文件,它类似mv命令,其实就是重命名。
    import shutil
    shutil.move('folder1', 'folder3')

    shutil.make_archive(base_name, format,...)
    创建压缩包并返回文件路径,例如:zip、tar
    创建压缩包并返回文件路径,例如:zip、tar
    •base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如:www                        =>保存至当前路径
    如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    •format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    •root_dir: 要压缩的文件夹路径(默认当前目录)
    •owner: 用户,默认当前用户
    •group: 组,默认当前组
    •logger: 用于记录日志,通常是logging.Logger对象


    #将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
    import shutil
    ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

    #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
    import shutil
    ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

    2. zip方式

    import zipfile

    # 压缩
    z = zipfile.ZipFile('laxi.zip', 'w')
    z.write('test.xml')
    z.write('xo.xml')
    z.close()


    # 解压   #解所有
    z = zipfile.ZipFile('laxi.zip', 'r')
    z.extractall()
    z.close()

    # 解压   #解单个
    z = zipfile.ZipFile('laxi.zip', 'r')
    z.extract('test.xml')
    z.close()

    3. tar 方式
    import tarfile

    # 压缩
    tar = tarfile.open('your.tar','w')
    tar.add('test.xml', arcname='test.log')    #重命名压缩
    tar.add('xo.xml', arcname='xo.log')         #重命名压缩
    tar.close()

    # 解压  #解压所有
    tar = tarfile.open('your.tar','r')
    tar.extractall()  # 可设置解压地址
    tar.close()

    #解压单个文件
    tar = tarfile.open('your.tar','r')
    obj = tar.getmember("test.log")
    tar.extract(obj)  # 可设置解压地址
    tar.close()

    五、 面向对像

    http://www.cnblogs.com/wupeiqi/articles/5017742.html


    实现邮件功能


    封装对像,对像即self,加载一次,反复使用

    什么时候用面向对像
        当某一些函数具有相同参数时,将参数值一次封装


    1. 面向对像实现操作SQL
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang

    class SQLHelper:
        def fetch(self,sql):
            print(obj.hhost)
            print(obj.uusername)
            print(obj.pwd)
            print(sql)
        def create(self,sql):
            pass
        def remove(self,nid):
            pass
        def modify(self,name):
            pass


    obj = SQLHelper()               #创建对像,即self,self即对像的本身,self即等于obj
    obj.hhost = "c1.salt.com"       #封装到对像
    obj.uusername = "alex"          #封装到对像
    obj.pwd = "123"                 #封装到对像

    obj.fetch('select * from A')  #使用对像的方法,先执行obj封装方法(即self),因为会把obj对像赋给self


    结果:
    c1.salt.com
    alex
    123
    select * from A   


    2. self 是什么鬼?
        self 是一个python自动给传的参数
        那个对像执行方法,self就是谁
        obj1.fetch('selec....')     self=obj1
        obj2.fetch('selec....')     self=obj2


    3. 构造方法
        类中有一个特殊的方法__init__,类()自动被执行 (所以我们可以做初始化的功能放到这里)


    ----__init__方法使用

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang

    class SQLHelper:
        def __init__(self,a1,a2,a3):                #__init__等于obj(),即对像()执行时调用自动执行
            print('自动执行init')
            self.hhost = a1
            self.uusername =a2
            self.pwd = a3
        def fetch(self,sql):
            print(obj.hhost)
            print(obj.uusername)
            print(obj.pwd)
            print(sql)
        def create(self,sql):
            pass
        def remove(self,nid):
            pass
        def modify(self,name):
            pass


    obj = SQLHelper('c1.salt.com','alex',123)      #类()自动执行__init__方法,所以我们可以对__init__进行操作
    obj.fetch('select * from A')                    #使用对像的方法

    结果:
    自动执行init
    c1.salt.com
    alex
    123
    select * from A
       
       

    3. 类的多次封装
    #类的二次封装,多层类调用,嵌套
    class c1:
        def __init__(self,name,obj):
            self.name = name
            self.obj = obj

    class c2:
        def __init__(self,name,age):
            self.name = name
            self.age = age

        def show(self):
            print(self.name)


    c2_obj = c2('aa',11)
    c1_obj = c1("alex",c2_obj)         #将c2_obj对像封装到c1_obj对像
    print(c1_obj.obj.age)              #obj.age调用c2类的方法的age变量


    结果:
    11


    #类的三次封装,嵌套调用
    class c1:
        def __init__(self,name,obj):
            self.name = name
            self.obj = obj

    class c2:
        def __init__(self,name,age):
            self.name = name
            self.age = age

        def show(self):
            print(self.name)
            print('show')

    class c3:
        def __init__(self,a1):
            self.money = 123
            self.aaa = a1

    c2_obj = c2('aa',11)
    # c2_obj 是c2 类型
    #-- name = 'aa'
    #-- age = 11
    c1_obj = c1("alex",c2_obj)        #将c2_obj对像封装到c1_obj对像
    # c1_obj 是c1 类型
    # -- name = 'alex'
    # -- obj = c2_obj
    c3_obj = c3(c1_obj)
    # 使用c3_obj执行show方法
    print(c3_obj.aaa.name)
    print(c3_obj.aaa.obj.age)        
    c3_obj.aaa.obj.show()

    结果:
    alex
    11
    aa
    show


    #类的三次封装,嵌套调用
    class c1:
        def __init__(self,name,obj):
            self.name = name
            self.obj = obj

    class c2:
        def __init__(self,name,age):
            self.name = name
            self.age = age

        def show(self):
            print(self.name)
            return 123

    class c3:
        def __init__(self,a1):
            self.money = 123
            self.aaa = a1

    c2_obj = c2('aa',11)
    # c2_obj 是c2 类型
    #-- name = 'aa'
    #-- age = 11
    c1_obj = c1("alex",c2_obj)        #将c2_obj对像封装到c1_obj对像
    # c1_obj 是c1 类型
    # -- name = 'alex'
    # -- obj = c2_obj
    c3_obj = c3(c1_obj)
    # 使用c3_obj执行show方法
    # print(c3_obj.aaa.name)
    # print(c3_obj.aaa.obj.age)
    ret = c3_obj.aaa.obj.show()
    print(ret)


    结果
    aa
    123

    4. 面向对像--继承
    #继承是把父类的代码复制过来一份

    class F1:                       #父类,基类
        def show(self):
            print('show')

        def foo(self):
            print(self.name)
    class F2(F1):                   #子类,派生类
        def __init__(self,name):
            self.name = name

        def bar(self):
            print('bar')
        def show(self):
            print('F2.show')

    obj = F2('alex')         #创建对像obj,给F2传值
    #obj.show()
    obj.foo()                #执行对像调用foo方法。执行是F1的foo

    结果
    alex

  • 相关阅读:
    独家全新2019超级签名源码/超级签/ios分发/签名端本地linux服务器完成签名带部署文档
    YYC松鼠短视频系统加入openinstall插件SDK实现免邀请码注册统计和安装统计-详细方法
    程序员男朋友没空搭理人吗?现实中程序员真的忙到女朋友都不要搭理了吗?
    献给攻击者,请放弃攻击吧,这样只会浪费自己的青春+金钱
    新奇怪知识:用ps导出gif图片放在网页上可实现只循环一次并且定格不变,本地一直循环
    uniapp配置去掉友盟无法打包,提示配置错误如何解决
    git切换分支报错error: Your local changes to the following files would be overwritten by checkout:
    数字信号处理--卷积的意义
    傅立叶分析和小波分析之间的关系?
    傅里叶变换:MP3、JPEG和Siri背后的数学
  • 原文地址:https://www.cnblogs.com/wangminghu/p/5612703.html
Copyright © 2020-2023  润新知