• 文件操作的相关内容


    一,初识文件操作

      使用python来读写文件是一个非常简单的操作,我们使用open()函数来打开一个文件,获取文件的句柄,然后通过句柄就可以进行各种各样的操作了.根据打开的方式不同能够执行操作也会有相应的差异.

    打开方式:  r,w,a,r+,w+,a+,rb,wb,ab,r+b,w+b,a+b  默认使用的是r(只读模式)

    二,文件路径

    文件路径  open('文件路径',mode = '模式' , encoding = "路径")

     文件路径

    1. 绝对路径,从磁盘的根目录寻找 或者 从互联网上寻找一个路径

    2. 相对路径(用的多). 相对于当前程序所在的文件夹 ../上一层文件夹

    read 读

    f = open("哈哈哈哈哈", mode="r", encoding="UTF-8")
    s = f.read()
    print(s)
    f.close() # 如果没有这句话, 你在下面的程序中如果删除这个文件. 就会报错
    f = open("d:/小护士模特少妇女网红.txt", mode="r", encoding="gbk")
    line1 = f.readline().strip() # 空白: 空格, 	, 
    
    line2 = f.readline().strip()
    print(line1)
    print(line2)
    f.close()
    f = open("d:/小护士模特少妇女网红.txt", mode="r", encoding="gbk")
    content = f.readlines() # 也是全都加载进来了.
    print(content)
    结果:['每天坚持一点, ', '每天努力一点, ', '每天多思考一点, ', '慢慢你会发现, ', '你的进步越来越大。 ']

    .read()一次性全部读出来  缺点:1,读取的大的文件的时候内存容易溢出 2,操作起来比较麻烦

    如果read()里面填值的话就是读取内容,读取的是字符

    .readliens()也是全部加载进来了,不过是列表的格式

    里面读取值的话也是读取这个行的内容,读取的也是字符

     

    *************这个是必须会写的*********************************

    # f是一个可迭代对象
    f = open("d:/周润发大战奥特曼.txt", mode="r", encoding="gbk") # 默认跟着操作系统走的  GBK
    for line in f:  # 内部其实调用的是readline()
        print(line.strip())
    f.close() # 关闭

     因为如果直接读取.readline()这样一句句打印的话,会出现一个问题,就是会打印多了一个

    你可以用刚才演示的办法.strip()去除文件里面的空白

    或者你也可以把print的默认值end= " "改成空格或者"*"

    ps:当你打开这个文件的时候,一定要养成好的习惯f.close()一下,就相当于医生做一台手术,光手术了,没有缝合,你就可以出去了,所以一定要.close()一下

    wirte写

    f = open("d:/sylar.txt", mode="w", encoding="utf-8")
    f.write("周笔畅
    ") # 写的时候. 先清空. 再写入. w
    f.write("胡辣汤
    ")
    f.write("实付款
    ")
    
    f.flush()#刷新
    f.close()#关闭
    

    当你写完文件的时候,一定要.flush()一下,刷新一下,这个添加的话是覆盖添加,就是之前写的文档东西都没有了,更新了一个新的文件夹,这个就是wirte不是一样的

    append 追加写

     

    f = open("d:/sylar.txt", mode="a", encoding="utf-8")
    f.write("娃哈哈") # 追加写
    f.write("爽歪歪")
    f.flush()
    f.close()

    这个就是追加写,和上面的write不一样,是在后面追加写的,但是和write一样一定要更新和关闭

    b------------文件拷贝

    首先你要了解b模式的话,你就应该要了解什么是b是什么,b是bit

     ascll码 只包含英文,数字,特殊字符

    gbk 都是两个字节

    万国码 Unicode 32bit   4个字节 可以兼容各个国家的文字,因为很浪费空间,所以进行改编

    utf-8  可变长度的Unicode  英文是1个字节   欧洲文字占用两个字节  中国文字是占用三个字节

    一个字节(byte)是8位(bit)

    所以b模式的话就是操作非文本文件的时候就用带b的,所以图形压缩包mp3 等等的都是带b的,他拷贝的是/x../系列的东西

     rb读取文件的bit

    f1 = open("d:/sylar.txt",mode="rb")
    for line in f1 :
        print(line)

    wb拷贝

    f1 = open("d:/sylar.txt",mode= "rb")
    f2 = open("f:/哈哈.txt",mode="wb")
    for line in f1 :
        f2.write(f1)
    f1.close()
    f2.flush()
    f2.close()

     ab追加以字节的形式往里面添加东西(但是不可以读所以不建议使用)若要用的话,a+b最合适了尤其是做断点续传的时候

    ***************************这个是必须会写的*********************************

     r+读写(唯一一个和光标无关的添加,在后面添加的)

    f = open("菜单", mode="r+", encoding="utf-8")  # r+最常见
    s = f.read(1) # 读取一个字符
    print(s)
    f.write("胡辣汤") # r+模式. 如果你执行读了操作. 那么写操作的时候. 都是写在文件的末尾. 和光标没有关系
    # f.write("ab") # 在文件开头写入. 写入的是字节,把原来的内容盖上
    
    # for line in f:
    #     print(line)
    # f.write("蛋炒饭")
    # 正确用法: 先读后写
    f.close()

    w+ 写读

    f = open("菜单", mode="w+", encoding="utf-8")  # 很少用.
    f.write("疙瘩汤")
    f.seek(0)   # 移动到开头
    content = f.read()
    print("读取的内容是", content)
    f.flush()
    f.close()

    a+ 追加写

    f = open("菜单", mode="a+", encoding="utf-8")
    f.write("韭菜鸡蛋饺子")
    
    f.seek(0)
    content = f.read()
    print(content)

    这样的话因为光标在后面所以可能会读出来,所以需要吧光标移动到第一个字符

    其他相关操作:

    1. seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的中部分要
    3的倍数.
    通常我们使用seek都是移动到开头或者结尾.
    移动到开头: seek(0)
    移动到结尾: seek(0,2) seek的第二个参数表⽰的是从哪个位置进行偏移, 默认是0,
    开头, 1表示当前位置, 2表示结尾 

    f = open ("小娃娃",mode = "r+",encoding = "utf-8")
    f.seek(0)  #光标移动到0
    countent = f .read()#读取内容,此时光标移动到结尾
    print(count)
    f.seek(0) #再次将光标移动到开头
    f.seek(0,2)将光标移动到结尾
    count2 = f.read()#读取内容 什么都没有
    print (count2)
    
    f.seek(0)  #移动到开头
    f.write("张国荣")  #写入信息,此时光标在9    (中文3*3个=9)
    
    f.flush()
    f.close()

    2.tell()使用可以帮我们获取到当前光标的位置

    f = open("小娃娃",mode = "r+",encoding = "uft-8")
    f.seek(0) #光标移动到开头
    content = f.read()#获取内容,此时光标移动到结尾
    print(content)
    
    f.seek(0)  #再次将光标移动到开头
    f.seek (0,2)  #将光标移动到结尾
    content2 = f.read()#读取内容  什么都没有
    print(content2)
    
    f.seek(0)  #再次移动到了开头
    f.write("麻花藤")   #写入信息,此时光标在9
    
    print(f.tell)  #获取光标位置9
    f.flush()
    f.close()

     3.truncate()截断文件

    f = open("小娃娃",mode = "w",encoding = "utf-8")
    f.write('哈哈")  #写入两个字符
    f.seek(3)  光标移动到3也就是两个字中间的位置
    f.truncate()  #删除光标后面的所有内容
    f.close()
    
    f = open("小娃娃",mode = "r+",encoding = "utf-8")
    content = f.read(3)  #读取12个字符
    s.seek(4)
    print(f.tell())
    f.truncate()  #后面的内容都删除
    f.flush()
    f.close()
    f = open("小娃娃",mode = "w",encoding = "utf-8")
    f.write('哈哈")  #写入两个字符
    f.seek(3)  光标移动到3也就是两个字中间的位置
    f.truncate()  #删除光标后面的所有内容
    f.close()
    
    f = open("小娃娃",mode = "r+",encoding = "utf-8")
    content = f.read(3)  #读取12个字节
    s.seek(4)
    print(f.tell())
    f.truncate()  #后面的内容都删除
    f.flush()
    f.close()

      深坑:在r+模式下,如果读取了内容,不论读取内容多少,光标显示是多少,在写入或者操作文件的时候都是在结尾进行操作.

    所以如果想做接到操作,记住要先挪动光标,挪动到 你想要截断的位置,然后再进行截断,关于truncate(n)  如果给出了n,则开头进行截断如果不给,则从当前位置截断,后面的内容将会被删除.

    ***************************这个是必须会写的*********************************

    修改文件以及另一种打开文件的方式

    文件修改:只能将文件中的内容读取到内存中,将信息修改完毕,然后将源文件删除,将新文件的名字改成老文件的名字.

    import os
    with open("小娃娃",mode = "r",endcoding = "utf-8")as f1,
    open("小娃娃",mode = "w",encoding = "ttf-8")as f2 :
    content = f1.read()
    new_countend = content.replace("冰糖葫芦","大白梨")
    f2.write(new_content)
    os.remove("小娃娃")  #删除源文件
    os.rename("小娃娃new","小娃娃") #重命名新文件
    
    弊端:一次将所有的内容读取出来,内存溢出.
    解决方法:一行一行的读取和操作
    import os
    with open("小娃娃",mode = "r",endcoding = "utf-8")as f1,
    open("小娃娃",mode = "w",encoding = "ttf-8")as f2 :
    for line in f1 : 
        new_countend = content.replace("冰糖葫芦","大白梨")
        f2.write(new_content)
    os.remove("小娃娃")  #删除源文件
    os.rename("小娃娃new","小娃娃") #重命名新文件

    代码练习:

    # 2,写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
    def func(lst):   # function
        # return lst[1::2]
    
        result = []
        for i in range(len(lst)):
            if i % 2 == 1:
                result.append(lst[i])
        return result
    
    # 3, 写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5
    def func(obj):
        # if len(obj) > 5:
        #     return True
        # else:
        #     return False
        return len(obj) > 5
    
    
    # 4, 写函数,检查传入列表的长度,如果大于2,将列表的前两项内容返回给调用者
    def func(lst):
        if len(lst) > 2:
            return lst[:2]
    
    
    # 5, 写函数,计算传入函数的字符串中, 数字、字母、空格 以及 其他内容的个数,并返回结果 isalpha()
    def func(s=""):
        shuzi = 0
        zimu = 0
        kongge = 0
        qita = 0
        for c in s:
            if c.isalpha():
                zimu = zimu + 1
            elif c.isdigit():
                shuzi = shuzi + 1
            elif c.isspace():
                kongge = kongge + 1
            else:
                qita = qita + 1
        return shuzi, zimu, kongge, qita
    
    print(func("abcd1234@@@@    "))
    
    # 6,写函数,接收两个数字参数,返回比较大的那个数字。
    def func(a, b):
        # if a > b:
        #     return a
        # else:
        #     return b
        return a if a > b else b
    
    # 三目运算
    # a = 100
    # b = 20
    #
    c = a if a > b else b
    print(c)
    
    # 7, 写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
    dic = {"k1": "v1v1", "k2": [11,22,33,44]}
        # PS:字典中的value只能是字符串或列表
    def func(dic):
        for k, v in dic.items():
            if len(v) > 2:
                v = v[:2]
                dic[k] = v
        return dic
    
    # 8, 8,写函数,此函数只接收一个参数且此参数必须是列表数据类型,
    # 此函数完成的功能是返回给调用者一个字典,
    # 此字典的键值对为此列表的索引及对应的元素。
    # 例如传入的列表为:[11,22,33] 返回的字典为 {0:11,1:22,2:33}。
    def func(lst):
        if type(lst) != list:
            print("扔出去一个异常")
    
        dic = {}
        for i in range(len(lst)):
            dic[i] = lst[i]
        return dic
    
    # 写函数,函数接收四个参数分别是:姓名,性别,年龄,学历。用户通过输入这四个内容,
    # 然后将这四个内容传入到函数中,此函数接收到这四个内容,
    # 将内容追加到一个student_msg文件中
    def func(name, age, edu, gender=""):
        f = open("student_msg", mode="a", encoding="utf-8")
        f.write(name+"_"+gender+"_"+age+"_"+edu+"
    ")
        f.flush()
        f.close()
    
    func("郑中基", "", "50", "大本")
    func("张学友", "", "60", "大本")
    
    while 1:
        tiwen = input("请问是否要输入学生信息输入任意内容继续,输入Q退出:")
        if tiwen.upper() == 'Q':
            break
    
        name = input("请输入你的姓名:")
        gender = input("请输入你的性别:")
        age = input("请输入你的年龄:")
        edu = input("请输入你的学历:")
    #
        gender = "" if gender == "" else ""
        func(name, age, edu, gender)
    
    # 11 写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作(升级题)。
    import os
    def func(file_name, old, new):
    
        with open(file_name, mode="r", encoding="utf-8") as f1, 
            open(file_name+"_副本", mode="w", encoding="utf-8") as f2:
            for line in f1:
                line = line.replace(old, new)
                f2.write(line)
        os.remove(file_name)
        os.rename(file_name+"_副本", file_name)
    
    
    # 12. 写一个函数完成三次登陆功能,再写一个函数完成注册功能. 用户信息写入到文件中
    #
    def regist(username, password): # wusir
        # 1. 检查用户名是否重复
        f = open("user_info", mode="r+", encoding="utf-8")
        for line in f:
            if line == "": # 防止空行影响程序运行
                continue
            user_info_username = line.split("_")[0]
            if username == user_info_username: # 用户名重复了
                return False
        else:
            # 2. 写入到文件中
            f.write(username+"_"+password+"
    ")
    
        f.flush()
        f.close()
        return True
    
    name, psw = input("请输入你的用户名:"), input("请输入你的密码:")
    print(regist(name, psw))
    
    def login(username, password):
        f = open("user_info", mode="r", encoding="UTF-8")
        for line in f:
            if line.strip() == username+"_"+password:
                f.close()
                return True
        else:
            f.close()
            return False
    
    for i in range(2, -1, -1):
        ret = login(input("请输入用户名:"), input("请输入密码:"))
        if ret:
            print("恭喜你. 登录成功")
            break
        else:
            print("用户名或密码错误, 还有%s次机会" % i)
  • 相关阅读:
    测试clang-format的格式化效果
    debian设置limits.conf
    可读性公式的python包+MLTD讲解
    SQL-1
    首届中文NL2SQL挑战赛-step7记录
    首届中文NL2SQL挑战赛-step6
    torch学习中的难点
    yield and send的使用详细解释
    ELMO及前期工作 and Transformer及相关论文
    LSTM参数和结构的本质理解——num_units参数/batch_size/cell计算
  • 原文地址:https://www.cnblogs.com/zhaodingding/p/9638165.html
Copyright © 2020-2023  润新知