• 文件操作的相关内容


    一,初识文件操作

      使用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)
  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/zhaodingding/p/9638165.html
Copyright © 2020-2023  润新知