python学习-第七章:常用模块--os、sys、re(二)

1、os模块

专门操作目录和文件的函数模块

import os

#os模块跟sys模块搭配使用,可以把当前目录的路径存放到系统缓存中
import sys
print(__file__)
print(os.path.abspath(__file__))
print(os.path.dirname(os.path.abspath(__file__)))
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

print(sys.path)

print(os.getcwd()) #当前工作目录
os.chdir("python") #切换目录
print(os.getcwd())
os.chdir(".")   #返回当前目录
print(os.getcwd())
os.chdir("..")   #返回上一目录
print(os.getcwd())

print(os.pardir) #获取当前目录的父目录字符串名:(..)
os.makedirs("filename1/filename2") #在当前目录下,创建多级目录
os.mkdir("filename1") #创建单个目录

os.chdir("filename1/filename2") #切换目录
print(os.getcwd())
os.removedirs("filename1/filename2") #删除多级目录,从最底层往上层删除,直到遇到目录下有文件时停止
os.rmdir("filename1") #删除单个目录

print(os.listdir()) #显示当前目录下所有文件和子目录,以列表形式展示

os.remove("aaa") #删除文件
os.rename("aaa", "bbb") #文件或目录重命名
os.rename("filename1", "filename")

print(os.stat("bbb"))   #获取文件或目录的详情,包括创建用户、时间、大小等等
print(os.stat("filename"))

print(os.sep)   #当前操作系统下的目录分隔符:win下\ linux下 /
print(os.linesep)   #输出当前平台使用的行终止符,win下为”t\n”, linux下为n”
print(os.pathsep)   #输出用于分割文件路径的字符串 win下为;, linux下为:

print(os.name) #输出字符串指示当前使用平台 win->'nt' ; linux->'posix'

print(os.system("help"))
print(os.system("pwd")) #执行shell命令,执行显示
print(os.environ)   #环境变量path

print(os.path.abspath("filename"))  #获取指定目录的绝对路径
print(os.path.split("filename")) #将指定目录的绝对路径分割两部分:第一个是目录的绝对路径,第二个是文件名
print(os.path.split(os.path.abspath("filename")))
print(os.path.dirname(os.path.abspath("filename"))) #返回path的目录。其实就是os.path.split (path) 的第一个元素
print(os.path.basename(os.path.abspath("filename"))) #返回path的文件名。其实就是os.path.split (path) 的第二个元素
print(os.path.exists(os.path.abspath("bbb.txt")))   #如果path存在,返回True; 如果path不存在,返回Ealse
print(os.path.isabs(os.path.abspath("bbb.txt")))    #如果path是绝对路径,返回True
print(os.path.isabs("filename"))
print(os.path.isfile("filename"))   #如果path是一个存在的文件,返回True。否则返回False
print(os.path.isfile("bbb.txt"))
print(os.path.isdir("filename"))    #如果path是一个存在的目录,则返回True。否则返回False
print(os.path.isdir("bbb.txt"))
print(os.path.join(os.path.abspath("filename"), "aaa", "bbb"))  #将多个路径组合后返回,第一个参数为绝对路径
print(os.path.getatime("bbb"))  #返回path所指向的文件或者目录的最后存取时间
print(os.path.getctime("bbb"))  #返回path所指向的文件或者目录的最后创建时间
print(os.path.getmtime("bbb"))  #返回path所指向的文件或者目录的最后修改时间

 

 

2、sys模块

操作当前操作系统的函数

import sys

print(sys.argv) #命令行参数List,第一个元素是程序本身路径
# sys.exit(0) #退出程序
print(sys.version) #获取Python解释程序的版本信息
print(sys.maxsize) #最大总数
print(sys.path) #环境变量path
print(sys.platform) #返回操作系统平台名称

#练习:生成进度条
import time
for i in range(50):
    # print("#", end="")
    sys.stdout.write("#")
    time.sleep(0.1)
    sys.stdout.flush()

 

3、re模块

  内嵌了正则表达式编程语言的模块,在python中用re模块实现正则表达式的匹配功能
  • 普通字符:大多数字符和字母都会和自身匹配
    r = re.findall("ab", "abcdefg123abcfg")
    print(r)    # ['ab', 'ab']

     

  • 元字符: . ^ $ * + ? [] | () \
  1.  . ^ $ * + ?
    # . --> 通配符:代表一个任意的字符
    r = re.findall("b.f", "abcdefg123abcfg")
    print(r)    # ['bcf']
    r = re.findall("b...f", "abcdefg123abcfg")
    print(r)    # ['bcdef']
    
    # ^ ---> 尖括号:代表从字符串开头开始匹配
    r = re.findall("^ab", "abcdefg123abcfg")
    print(r)    # ['ab']
    
    # $ ---> 代表从字符串结尾匹配
    r = re.findall("fg$", "abcdefg123abcfg")
    print(r)    # ['fg']
    
    
    # * + ? ---> 都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成情性匹配
    # * ---> 重复数量(0, 无穷大)
    r = re.findall("fg*", "abfcdefgg123abcfggggfg")
    print(r)    # ['f', 'fgg', 'fgggg', 'fg']
    r = re.findall("fg*?", "abfcdefgg123abcfggggfg") #后边加个? 最少匹配
    print(r)    # ['f', 'f', 'f', 'f']
    
    # + ---> 重复数量 (1, 无穷大)
    r = re.findall("fg+", "abfcdefgg123abcfggggfg")
    print(r)    # ['fgg', 'fgggg', 'fg']
    r = re.findall("fg+?", "abfcdefgg123abcfggggfg") #后边加个? 最少匹配
    print(r)    # ['fg', 'fg', 'fg']
    
    # ? ---> 重复数量 (0, 1)
    r = re.findall("fg?", "abfcdefgg123abcfggggfg")
    print(r)    # ['f', 'fg', 'fg', 'fg']
    r = re.findall("fg??", "abfcdefgg123abcfggggfg") #后边加个? 最少匹配
    print(r)    # ['f', 'f', 'f', 'f']

  2. []字符集
    # [] ---> 字符集:交集匹配
    r = re.findall("[xy]", "xyuuuu")
    print(r)    #['x', 'y']
    r = re.findall("a[xu]b", "aaxbyuuuaubb")
    print(r)    #['axb', 'aub']
    r = re.findall("a[,.*$+]", "a+axa*bya$uua,ua.ubb")  # * $ . + --> 特殊的元字符,在字符集中就失效了
    print(r)    #['a+', 'a*', 'a$', 'a,', 'a.']
    
    # 在[]字符集中不失效的特殊符号 ---> ^ - \
    r = re.findall("[1-9]", "23456dhb33")
    print(r)    # ['2', '3', '4', '5', '6', '3', '3']
    r = re.findall("[a-z]", "23456dhb33")
    print(r)    # ['d', 'h', 'b']
    r = re.findall("[^dh]", "256dhb3")  #
    print(r)    # ['2', '5', '6', 'b', '3']
    r = re.findall("[^a-z]", "56dhb33")  #
    print(r)     # ['5', '6', '3', '3']
    
    """
        反斜杠后边跟元字符去除特殊功能,比如\
        反斜杠后边跟普通字符实现特殊功能,比如\d
        \d 匹配任何十进制数,它相当于类[0-9]
        \D 匹配任何非数字字符;它相当于类 [^O-9]。
        \s 匹配任何空白字符;它相当于类[\t\n\r\f\v]。
        \S 匹配任何非空白字符,它相当于类[^\t\n\r\f\v]。
        \w 匹配任何字母数字字符;它相当于类 [a-zA-ZO-9_]
        \W 匹配任何非字母数字字符,它相当于类[^a-zA-ZO-9_]
        \b 匹配一个特殊字符边界,比如空格 ,&,#等
    """
    r = re.findall("[\d]", "56dhb33")
    print(r)    # ['5', '6', '3', '3']
    r = re.findall("[\D]", "56dhb33")
    print(r)    # ['d', 'h', 'b']
    
    #使用^特殊符号计算,如下:
    sum = "12 + (34 * 6 + 2 - 5 * (2-1))"
    r1 = re.findall("\\([^()]+\\)", sum)
    print(r1)    # ['(2-1)']

  3. ()分组
    #()---> 元字符分组
    r = re.findall("(ad)+", "adddad")
    print(r)    # ['ad', 'ad']
    r = re.findall(r"(ad)+", "adddad")
    print(r)    # ['ad', 'ad']
    
    # (?P<key> 【元字符】) 这样可以把字符串分组,并通过key单独获取,默认获取第一个
    r = re.search("(?P<name>\w{3})/(?P<id>\d{2})", "com/23")
    print(r)    # <re.Match object; span=(0, 6), match='com/23'>
    print(r.group())    # com/23
    print(r.group("name"))     # com
    print(r.group("id"))       # 23
    
    r = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "cxf20chenglong50lianjie60")
    print(r.group())    # cxf20
    print(r.group("name"))  # cxf
    print(r.group("age"))   # 20
    
    r = re.match("a", "babc")   # 同search,不过是在字符串开始处进行匹配
    print(r)
    # print(r.group())    # None

     

  4. | 管道
    # | ---> 管道:交集
    r = re.findall("www.(baidu|oldboy).com", "www.oldboy.com")  # 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    print(r)    # ['oldboy']
    r = re.findall("www.(?:baidu|oldboy).com", "www.oldboy.com") # ?: ---> 去掉元字符匹配优先级,把整个字符串作为匹配对象
    print(r)    # ['www.oldboy.com']
    r = re.split("[ |]", "hello abc|efg")  # split:分割
    print(r)    # ['hello', 'abc', 'efg']
    r = re.split("[ab]", "asbdg")   # 先按’a'分割得到'' 和'sbdg’,在对 '' 和 'sbdg' 分别按 'b' 分割
    print(r)    # ['', 's', 'dg']

     


  5. \ 反斜杠
    # sub --> 替换
    r = re.sub("A", "&", "asfgAdsfgA4567dAgs")
    print(r)    # asfg&dsfg&4567d&gs
    r = re.sub("\d", "%", "asfgAdsfgA4567dAgs", 2) # 最后一个参数是规定匹配次数
    print(r)    # asfgAdsfgA%%67dAgs
    r = re.subn("\d", "$", "abc2d4h5")      # 可以统计匹配次数
    print(r)    # ('abc$d$h$', 3)
    print(r[1])     # 3
    
    # compile --> 提前定义好匹配规则对象,后边直接使用即可
    # 好处:1、提前设置好规则,后边都可以调用,2、节省代码量,易维护
    ma = re.compile("\d")
    r = ma.findall("aa34bbb67")
    print(r)    # ['3', '4', '6', '7']
    
    # finditer --> 把匹配到的数据生成迭代器,可以进行循环遍历
    r = re.finditer("\d+", "sdhjj4567jdf67ghf7fg6")
    print(r)    # <callable_iterator object at 0x0000025C2CF9C3A0>
    for i in r:
        print(i.group())
    
    #循环遍历后结果:
    """
        4567
        67
        7
        6
    """

     


 4、文件存入模式

  • json
    主要用于结构化存放数据,可以不同语言和环境下通用,方便接口联调
    # json字符串格式:其实就是字典的key-value格式,如下:
    """
        {
            "name": "cxf",
            "age": "30",
            "sex": "male",
            "info": {
                "school": "aaa",
                "grade": "bbb",
                "address": "ccc",
            }
        }
    """
    # 注意:json字符串存入到文件中后,都是双引号
    
    # -------------------------------json
    import json
    
    # 这里存入到文件中,格式分别如下:
    dic = {'name':'cxf'}    # --->'{"name":"cxf"}'
    i = 20           # --->'20'
    l = 'hello'     # --->"hello"
    li = [22,34]    # ---> "[22,34]"
    
    # 写入
    fi = open("json.txt","w")
    
    # dic_json = json.dumps(dic)
    # fi.write(dic_json)
    json.dump(dic, fi)  # 这里代码等于上边两行代码,简洁操作
    
    fi.close()
    
    # 读取
    fi = open("json.txt","r")
    
    # str_json = json.loads(fi.read())
    str_json = json.load(fi) # 这里代码等于上边一行代码,省略了fi.read()操作
    
    print(str_json)
    print(type(str_json))
    
    fi.close()

     

  • pickle
    功能跟json差不多,但是比json可存入的对象更全,但是不建议使用
    # -------------------------------pickle
    import pickle
    
    # 存入到文件中是不可读状态,并且一般都是python之间使用,跨语言不可识别
    dic = {"name" : "chenglong", "age" : 18, "sex" : "male"}
    # print(type(dic))
    
    # 写入
    fi = open("pickle.txt","wb")   # 注意w是写入str,wb是写入bytes,j是'bytes‘
    
    # data = pickle.dumps(dic)
    # fi.write(data)
    pickle.dump(dic, fi)
    
    fi.close()
    
    # 读取
    fi = open("pickle.txt", "rb")
    
    # pickle_str = pickle.loads(fi.read())
    pickle_str = pickle.load(fi)
    
    print(pickle_str)
    
    fi.close()

     

  • shelve
    shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写:key必须为字符串,而值可以是python所支持的数据类型
    # -------------------------------shelve
    import shelve
    
    # 目的:将一个字典放入文本,并且是追加的方式写入
    fi = shelve.open(r"shelve.txt")
    
    fi['stu1_info']={'name':'alex', 'age':1}
    fi['stu2_info']={'name':'alvin', 'age':'20'}
    fi['school_info']={'website':'oldboyedu.com','city':"beijing"}
    
    # shelve会生成三个文件:不过都是人为不可读的,需要通过方法读取
    # shelve.txt.bak
    # shelve.txt.dat
    # shelve.txt.dir
    
    # fi.get(key) 这里读取出来后是存入时的数据类型,可以直接使用
    print(fi.get("stu1_info"))
    print(type(fi.get("stu1_info")))
    print(fi.get("stu1_info")["name"])
    print(fi.get("stu2_info"))
    print(fi.get("school_info"))
    
    fi.close()

     

  • xml
    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单

    xml格式:

    #xml文件中存入格式:
    """
        <?xml version="1.0" encoding="utf-8" ?>
        <data name="subject">
            <subject name="english">
                <teacher age="18">罗翔</teacher>
                <sorce>90</sorce>
                <important name="very" value="6"/>
            </subject>
            <subject name="maths">
                <teacher age="60">华先生</teacher>
                <sorce>120</sorce>
                <important name="max" value="8"/>
            </subject>
            <subject name="physics">
                <teacher age="50">Josh</teacher>
                <sorce>60</sorce>
                <important name="min" value="3"/>
            </subject>
        </data>
    
    """
    

      xml文件的增删改查操作:

    # ET表示别名
    import xml.etree.ElementTree as ET
    
    tree = ET.parse("test.xml")
    root = tree.getroot()   #首先获取根节点数据
    print(root)
    print(root.tag)
    
    # --------------------------------------查询xml
    # 利用遍历根节点的方式,获取其下所有子节点
    for i in root:
        # print(i)
        print(i.tag, i.attrib)
        for j in i:
            # print(j)
            print(j.tag, j.attrib, j.text)
    
    # 只遍历根节点下的某一个子节点
    for i in root.iter("sorce"):
        print(i.tag, i.attrib, i.text)
    
    # --------------------------------------修改xml
    
    for node in root.iter("sorce"):
        node.text = str(int(node.text) + 1)
        node.set("updated", "yes")
    
    #直接写入,这里需要设置字符集,否则xml文件的中文不可读
    tree.write("test.xml", encoding="utf8")
    
    # --------------------------------------创建xml
    import time
    
    # 注意:xml中必须都是字符串,不能是数值格式
    new_xml = ET.Element("nameList")
    name = ET.SubElement(new_xml,"name", attrib={"enrolled":"yes", "ctime": str(time.localtime().tm_year)})
    age = ET.SubElement(name, "age", attrib={"checked":"no"})
    age.text='33'
    sex = ET.SubElement(name, "sex")
    sex.text = "male"
    
    name2 = ET.SubElement(new_xml,"name", attrib={"enrolled":"no"})
    age2 = ET.SubElement(name2, "age")
    age2.text='19'
    
    #写入xml
    et = ET.ElementTree(new_xml)
    et.write("new_test.xml", encoding="utf8", xml_declaration=True)
    
    # 打印生成的xml格式
    ET.dump(new_xml)
    
    # --------------------------------------删除xml中元素
    
    import xml.etree.ElementTree as ET2
    
    tree = ET2.parse("new_test.xml")
    root = tree.getroot()   #首先获取根节点数据
    print(root)
    print(root.tag)
    
    for node in root.findall("name"):
        print(node.find("age").text)
        if int(node.find("age").text) < 20:
            root.remove(node)
    
    tree.write("out_test.xml")

     

posted on 2023-12-27 09:17  飞鱼梦想  阅读(310)  评论(0)    收藏  举报