• Python操作文件


    操作文件的核心思路
      1. 确定操作文件的路径,是相当路径还是绝对路径
      2. 确定操作文件的宏观方式,是文件还是文件
      3. 操作文本文件,类似于字符串的操作方法
      4. 操作二进制文件,主要用于网络传输、下载媒体文件
      5. 通过 open 打开文件
      6. 通过 readwrite 方法读写文件
      7. 对文件操作完毕则关闭文件
      # 基本上对应文本文件时按处理,对于二进制文件按处理
      # 我们把这中方式称为 流处理,Linux上sed命令
      # 我们也可以通过with关键字语块结束从而自动关闭文件
      # 相对路径是相对当前文件路径,绝对路径是相对于根目录

    # 读取文件
    file_name = "song.txt"
    
    # 读取文件, r 只读模式, 读取文件需要指定文本文件的字符编码
    f = open(file_name, "r", encoding="utf-8")
    # 读取一行文本数据
    line = f.readline()
    print(line)
    
    # 遍历所有行
    for line in f:
        print(line)
    
    # 获取所有行的
    # 因为读指针已经移动到文件的结束, 所有 readlines会返回空列表
    # readlines会把文件数据全部读取进入内存,以换行符进行分割
    lines = f.readlines()
    print(lines)
    
    # 移动读指针到文件开始, 移动是以字节为单位
    f.seek(0)
    lines = f.readlines()
    print(lines)
    # 文件操作完毕,需要关闭文件
    f.close()

    修改文件的思路
      1. 读取原文件
      2. 新建临时文件
      3. 读一行修改一行,把修改好的文件写入临时文件
      4. 修改完,用临时文件替换原文件

    用户替换文件内容的程序

      1. 用户通过 python replace.py old_str new_str filename 替换文件内所有文件

      2. 替换完毕打印替换了多少次

    import os
    
    
    def flow_change(filename, old=None, new=None):
        """流式修改文件
    
        读原文件,把修改写入新文件,读完修改完则用新文件替换掉原文件
        """
        # 验证文件是否存在, old 和 new 是否有数据
        replece_count = 0
        if old and new and os.path.exists(filename):
            temporary_file = filename + "temp"
            with open(filename, "r", encoding="utf-8") as f_old, 
                    open(temporary_file, "w", encoding="utf-8") as f_new:
                # 流式遍历文件,读取一行处理一行,写入一行
                for line in f_old:
                    replece_count += line.count(old)
                    temp_line = line.replace(old, new)
                    f_new.write(temp_line)
    
            # 新文件替换原文件
            os.replace(temporary_file, filename)
    
            # 返回替换次数
            return replece_count
    
    
    if __name__ == '__main__':
        # 获取命令行参数, 序列解包方式获取数据,  sys.argv[1:4]
        old, new, file_name = ['你却未看过一眼', "那一眼成永远", "song.txt"] # 模拟用户命令行输入
        # 调用函数修改
        flow_change(file_name, old, new)
    

      

    用户登录程序

      1. 用户输入用户名和密码进行登录

      2. 用户信息存储在文件内

      3. 用户登录时候输错3次密码则锁定用户,下次不让登录

    class Login(object):
        """验证用户登录"""
        def __init__(self):
            self.__pwd_file = "user_pwd.txt"
            self.__pwd_data = self.get_pwd_data()
            self.__retries = {}
    
        def run(self):
            """模板方法模式, 组合其他方法"""
            while True:
                # 获取用户输入
                username = self.user_input("请输入用户名:")
                pwd = self.user_input("请输入密码")
    
                # 设置用户尝试次数
                self.__retries.setdefault(username, 0)
                # 检查用户登录状态
                enter_status = self.check_user(username, pwd)
                # 用户锁定或尝试次数达3次退出
                if enter_status:
                    break
    
        def check_user(self, username, pwd):
            """校验用户是否登录"""
            user_info = [i for i in self.__pwd_data if username in i]
            if user_info:
                user, user_pwd, is_enter = user_info[0]
            else:
                print("密码或账号错误")
                return
    
            # 检查用户的密码 输错一次则尝试加一
            if pwd != user_pwd:
                self.__retries[username] += 1
                print("账号或密码错误")
                # 检查用户是否锁定或尝试次数是否小于三次
                if self.__retries[username] >= 2:
                    self.lock_user(username)
                    print("账号{}已经锁定,禁止登录".format(username))
                return
    
            # 检查账户是否锁定
            if is_enter == "0":
                print("账号{}已经锁定,禁止登录".format(username))
                return
    
            print("你好{}, 登录成功".format(username))
            return True
    
        def lock_user(self, username):
            """锁定用户"""
            result = []
            for item in self.__pwd_data:
                user, user_pwd, is_enter = item
                if username == user:
                    result.append("{} {} {}
    ".format(username, user_pwd, "0"))
                else:
                    result.append(" ".join(item) + "
    ")
            self.__pwd_data = result
            # 写入修改
            self.write_change()
    
        def write_change(self):
            """写入修改, 只有账号锁定时写入修改"""
            temp_file = self.__pwd_file + "tmp"
            with open(temp_file, "w", encoding="utf-8") as f:
                f.writelines(self.__pwd_data)
    
            # 替换文件
            os.replace(temp_file, self.__pwd_file)
    
        def user_input(self, prompt):
            """获取用户输入"""
            while True:
                data = input(prompt).strip()
                if data:
                    return data
    
        def get_pwd_data(self):
            """获取用户存储的信息"""
            with open(self.__pwd_file, "r", encoding="utf-8") as f:
                pwd_data = [i.split() for i in f.readlines()]
            return pwd_data
    if __name__ == '__main__':
        login = Login()
        login.run()
    

      

    file object -- 文件对象
    对外提供面向文件 API 以使用下层资源的对象(带有 read() 或 write() 这样的方法)。根据其创建方式的不同,文件对象可以处理对真实磁盘文件,对其他类型存储,或是对通讯设备的访问(例如标准输入/输出、内存缓冲区、套接字、管道等等)。文件对象也被称为 文件类对象 或 流。

    实际上共有三种类别的文件对象: 原始 二进制文件, 缓冲 二进制文件 以及 文本文件。它们的接口定义均在 io 模块中。创建文件对象的规范方式是使用 open() 函数

    text file -- 文本文件
    一种能够读写 str 对象的 file object。通常一个文本文件实际是访问一个面向字节的数据流并自动处理 text encoding。文本文件的例子包括以文本模式('r' 或 'w')打开的文件、sys.stdin、sys.stdout 以及 io.StringIO 的实例

    text encoding -- 文本编码
    用于将Unicode字符串编码为字节串的编码器。

    sys.stdin
    sys.stdout
    sys.stderr
    解释器用于标准输入、标准输出和标准错误的 文件对象:
    stdin 用于所有交互式输入(包括对 input() 的调用);
    stdout 用于 print() 和 expression 语句的输出,以及用于 input() 的提示符;
    解释器自身的提示符和它的错误消息都发往 stderr。
    这些流都是常规 文本文件,与 open() 函数返回的对象一致


    Bytes类型 binary 二进制
    数据存储到硬盘,硬盘只能存储二进制
    网络传输也只能是二进制

  • 相关阅读:
    Eclipse查看源码
    让你的Eclipse的智能感知也和Visual Studio 一样快
    关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
    C#中Dictionary的用法及用途实例
    不想人工干预地自动执行存储过程?当目的表发生变动时自动执行相应的存储过程?
    再说HelloWorld
    TreeList应用(三) 收藏
    DataTable转换为List<Model>的通用类
    U盘不显示盘符
    如何在 Eclipse 中显示行号
  • 原文地址:https://www.cnblogs.com/2bjiujiu/p/13768366.html
Copyright © 2020-2023  润新知