Python文件与文件路径的操作

本文详细介绍了文件的打开、关闭、读取、写入以及文件定位操作,包括不同打开模式的使用,如只读、只写、追加等。还讲解了文件的复制、重命名方法,并通过实例展示了如何实现通讯录程序,实现新建和查询联系人功能。最后,讨论了目录操作,如创建、删除目录,获取文件列表,以及文件路径的相关操作,如获取当前路径、判断路径有效性等。
摘要由CSDN通过智能技术生成

文件与文件路径的操作

​ 程序员在运行程序的过程中往往会产生一些零时数据,但程序结束后,这些零时数据也会随之消失。那么有没有办法将这些数据持久化到磁盘中呢?当然是可以的,计算机文件会永久保存运行时产生的数据。

1.文件的打开和关闭

​ 想要将数据写入到文件中,需要先打开文件,数据写完之后,需要将文件关闭以释放内存。

1.1.文件的打开

​ Python提供函数open()打开文件,该函数调用成功会返回一个文件对象,语法格式如下:

open(file,mode='r',encoding=None)
# 参数file表示要打开的文件名
# 参数encoding表示打开文件的编码格式
# 参数mode设置文件的打开模式,其常用的模式如下:
r:以只读的方式打开文件,默认值
w:以只写的方式打开文件;
a:以追加的方式打开文件。

在实际的开发过程中,文件的打开模式可以搭配b、+使用,具体搭配如下表:

打开模式名称描述
r/rb只读模式以只读的形式打开文件/二进制文件,若文件不存在或无法找到,open()函数将调用失败
w/wb只写模式以只写的形式打开文件/二进制文件,若文件已存在,则重写文件,否则创建文件
a/ab追加模式以只写的形式打开文件/二进制文件,只允许在文件末尾追加数据,若文件不存在,则创建新文件
r+/rb+读取(更新)模式以读写的形式打开文件/二进制文件,如果文件不存在,open()函数调用失败
w/wb+写入(更新)模式以读写的形式创建文件/二进制文件,若文件已存在,则重写文件
a+/ab+追加(更新)模式以读写的形式打开文件/二进制文件,但只允许在文件末尾添加数据,若文件不存在,则创建新文件

1.2.文件的读取

文件的读取有3种方式,read(),readline(),readlines():

  • read():从指定文件中读取指定数据;
文件对象.read([size])
# 参数size用于设置读取数据的字节数,若没有则一次读取文件的所有数据
  • readline():从指定文件读取一行数据;
文件对象.readline()
  • readlines():一次读取文件的所有数据。
文件对象.readlines()
# 使用readlines()方法读取数据后回返回一个列表,文件的每一行对应列表中的一个元素 

1.3.文件的关闭

​ Python内置函数close()用于关闭文件,该方法不需要参数,直接调用。计算机的内存打开文件的数量是有限的,打开的文件占用系统的资源,降低系统的性能。因此需要用close()方法主动关闭不再使用的文件。

文件对象.close()
# 文件的打开
"""
file:文件名
mode:文件打开的方式,r-只读打开,w-只写打开,a-追加打开
encoding:字文件的编码格式,常见gbk和utf-8
返回值是一个文件对象
"""
txt = open("test.txt", mode='r', encoding="utf-8")
print(txt)
# 文件的读取
print("read():")
buff01 = txt.read()
print(buff01)
print("读取文件n个字节数:")
txt = open("test.txt", mode='r', encoding="utf-8")
print(txt.read(2))
# 读取文件一行数据
txt = open("test.txt", mode='r', encoding="utf-8")
print("readline():")
buff02 = txt.readline()
print(buff02)
# 读取文件所有数据
txt = open("test.txt", mode='r', encoding="utf-8")
print("readlines():")
buff03 = txt.readlines()
print(buff03)
# 文件的关闭
txt.close()

2.文件的读写操作

Python提供了write()方法和writlines()方法向文件写入数据:

  • write()
文件对象.write(str)
# str表示要写入的字符串,若写入成功,则返回本次写入的文件长度
  • writelines()
文件对象.write([str])
# 向文件写入字符串序列
# 文件的打开
file = open('a.txt', 'w', encoding='utf-8')
# 文件的写入,若文件不存在,会创建,若文件存在,不执行write()写入内容,会清空内容
# \n 表示换行,如果没有不会换行
print("write()...")
file.write("hello world\n")
file.write("人生苦短,快用Python")

# 文件的打开
file = open('a.txt', 'w', encoding='utf-8')
# writelines()向文件写入字符串序列
print("writelines()...")
str = ["\n" + "life is short,you need python",'\nPython好学']
file.writelines(str)

# 关闭
file.close()

3.文件定位读取

​ 在系统中文件的一次打开和关闭之间的读写操作都是连续的。程序总在上次读写的位置进行读写操作,但有时候会指定到某一位置来进行读写操作,这个时候我们就要用到文件读写位置的属性来进行操作。

​ Python提供用于获取文件读写位置及修改文件读写位置的tee()和seek()方法。

3.1.tell()方法

​ tell()方法用于获取当前文件读写的位置,格式为:

text.tell()
# 文件的打开
file = open('a.txt', 'r', encoding='utf-8')
print(file.read(5))  # 读取5个字节
print(file.tell())  # 15 输入文件读取的位置(汉字为3个字节)

3.2.seek()方法

​ seek()方法用于设置当前文件读写的位置,格式为:

txt.seek(offset,from)

​ seek()方法的参数offsert表示偏移量, 即读写位置需要移动的字节数;参数from用于指定文件的读写位置,该参数的取值有以下三个:

  • 0:表示在开始位置读写

  • 1:表示在当前位置读写

  • 2:表示在末尾位置读写

file = open(‘a.txt’, ‘w’, encoding=‘utf-8’)
file.seek(3,0)
print(file.write(“你好!!”))
file.close()




## 4.文件的复制和重命名

### 4.1.文件的复制

​	文件的复制即创建文件的副本,此项操作的本质仍是文件的打开、关闭和读写操作。复制文件的基本步骤如下:

1. 打开文件;
2. 读取文件内容;
3. 创建新的文件,将数据写入到文件中;
4. 关闭文件,保存数据。

具体实现如下:

```shell
# 文件的复制
file_name = "test.txt"
source_file = open(file_name,"r",encoding="utf-8")
all_data = source_file.read()
flag = file_name.split(".")
new_file = open(flag[0] + '备份' + ".txt",'w',encoding="utf-8")
new_file.write(all_data)
source_file.close()
new_file.close()

4.2.文件的重命名

​ Python提供了直接用于更改文件名的函数rename(),该函数的语法如下:

rename(源文件名,新文件名)

需要注意的是:这个函数存在于os模块中,需要导入os模块才能使用:

# 文件的复制
import os
os.rename("test.txt","test01.txt")

需要注意的是:需要重命名的文件必须存在,否则会报错。对于操作系统来说,文件和文件夹都是文件,所以该函数也对文件夹有效:

import os
# os.rename("test.txt","test01.txt")
os.rename("测试","重命名")

5.练习:通讯录

​ 要求编写通讯录程序,接收用户输入的姓名、电话、qq号、邮箱等信息,将这些信息保存到"通讯录.txt"文件中,实现新建联系人功能;可根据用户输入的联系人姓名查找联系人,展示联系人的姓名、电话等信息,实现查询功能。

import sys
import json
class TelephoneBook:
    def show_menu(self):  # 用于界面展示
        print("*" * 20)
        print("欢迎使用[通讯录] V1.0")
        print("1. 新建联系人")
        print("2. 查询联系人")
        print("0. 退出系统")
        print("*" * 20)
    def add_info(self):
        name_str = input("请输入姓名:")
        phone_num = input("请输入电话:")
        qq_num = input("请输入QQ号码:")
        mail_adr = input("请输入邮箱:")
        # 将数据封装到字典中
        card_dict = {"姓名": name_str, "手机号": phone_num,
                     "qq": qq_num, "mail": mail_adr}
        f = open("通讯录.txt", mode='a+', encoding='utf-8')
        # 将字典转换为str,然后再使用write()写入到通讯录的文本文件中
        f.write(str(card_dict) + '\n')
        f.close()
        print(f"成功添加{name_str}为联系人")
    # 显示联系人信息
    def show_info(self):
        file = open("通讯录.txt", mode='r', encoding='utf-8')
        # 如果通讯录.txt文件不为空时,执行下面代码
        if len(file.read()) != 0:
            # 保证每次从开始位置读取
            file.seek(0, 0)
            # 读取通讯录.txt文件中的内容
            file_data = file.read()
            # 对字符串进行分隔
            split_info = file_data.split('\n')
            # 删除多余的字符串
            split_info.remove(split_info[len(split_info) - 1])
            name = input("请输入要查询的姓名:")
            name_li = []       # 用于存储联系人姓名的列表
            all_info_li = []   # 用于存储所有信息的列表
            for i in split_info:
                # 将单引号替换为双引号
                dict_info = json.loads(i.replace("\'", '\"'))
                all_info_li.append(dict_info)
                # 获取所有联系人的姓名
                name_li.append(dict_info['姓名'])
            if name in name_li:
                for person_info in all_info_li:
                    for title_key, name_value in person_info.items():
                        if name_value == name:
                            for title, info_value in person_info.items():
                                print(title + ":" + info_value)
            else:
                print('联系人不存在')
        else:
            print("通讯录为空")
    def main(self):
        while True:
            self.show_menu()
            action_str = input("请选择操作功能:")  # 判断用户输入的功能指令
            if action_str.isdigit() is True:
                if int(action_str) == 1:
                    self.add_info()
                elif int(action_str) == 2:
                    self.show_info()
                elif int(action_str) == 0:
                    sys.exit()
            else:
                print('请输入正确的指令')
if __name__ == '__main__':
    tb = TelephoneBook()
    tb.main()

6.目录的操作

​ os模块定义了一些用于处理文件夹的操作函数,例如创建目录、获取文件列表等函数;除了os模块外,Python中的shutil模块也提供了文件夹的操作。

6.1.创建目录

​ os模块提供了mkdir()函数用于创建目录,语法格式为:

os.mkdir(path,mode)
  • path:表示要创建的目录,参数mode表示目录的数字权限,该参数在Windows系统下可以忽略。

在创建目录的操作中需要判断目录是否存在,如果存在则提示用户,如果不存在则可以创建并可写入数据:

# 创建目录
import os
dir_path = input("请输入要创建目录:")
# 判断目录是否存在
y_or_n = os.path.exists(dir_path)
if y_or_n is False:
    os.mkdir(dir_path)
    new_file=open(os.getcwd()+"\\"+dir_path+"\\"+"dir_demo.txt","w",encoding="utf-8")
    new_file.write("life is short, use Python.")
    print("写入成功")
else:
    print("该目录已经存在!")   

6.2.删除目录

​ 使用shutil模块的rmtree()函数可以实现删除目录,语法格式为:

rmtree(path)
path为要删除的目录
# 删除目录
import os
import shutil
# 判断目录是否存在
print(os.path.exists("重命名"))
shutil.rmtree("重命名")
# 确认目录是否删除
print(os.path.exists("重命名"))

6.3.获取目录的文件列表

​ os模块中的listdir()函数用户获取文件夹下文件或文件名的列表,该列表按字母顺序排序,语法格式为:

listdir(path)
# 获取文件夹列表
current_path = r"D:\Software"
print(os.listdir(current_path))

7.文件路径操作

7.1.相对路径路径和绝对路径

​ 文件的相对路径指某文件(或目录)所在的路径与其他文件(或目录)的路径关系,绝对路径指从盘符开始到当前位置的路径。os模块提供了用于检测目标路径是否是绝对路径isabs()函数和将相对路径规范化为绝对路径的abspath()函数。

  • isabs()函数

当目标路径为绝对路径时,isabs()函数会返回True,否则会返回False。

# 路径操作
import os
print(os.path.isabs("test01.txt"))
print(os.path.isabs("D:\Software"))
  • abspath()函数

当目标文件为相对路径时,使用该函数可以将路径规范化为绝对路径:

print(os.path.abspath("test01.txt"))

7.2.获取当前路径

​ 当前路径即文件、程序或目录当前所处的路径,os模块提供了getcwd()函数用于获取当前路径:

current_path = os.getcwd()
print(current_path)

7.3.检测路径的有效性

​ os模块中的exists()用于判断路径是否存在,如果当前路径存在,函数返回True,如果不存在则返回False。

# 判断路径是否存在
import  os
current_path = "D:\Software"
current_path_file = "D:\Software\jdk-17.0.2"
print(os.path.exists(current_path))  # True
print(os.path.exists(current_path_file))  # True

7.4.路径的拼接

os模块中join()函数用于拼接,语法格式为:

os.path.join(path1,[path2,....])
import os
path01 = "D:\Software"
path02 = "jdk-17.0.2"
# windows下默认使用/分隔
sumpath = os.path.join(path01, path02)
print(sumpath)

# 如果后面路径为空,则用\来结尾
path03 = ""
sumpath02 = os.path.join(path01, path03)
print(sumpath02)

8.练习:实现用户登录

​ 登录用户通常分为普通用户登录,管理员登录。在用户登录时,可以根据自身的权限进行选择登录。

要求:

  • 实现普通用户和管理员的登录
  • 管理员账号密码在程序中设置,普通用户账号与密码通过注册功能添加
  • 创建文件u_root.txt,写入管理员:
{'rnum': 'root', 'rpwd': '123456'}
# author by Michealzou@126.com
# 2022/5/12 19:24
import os


# 判断是否首次使用系统
def is_first_start():
    if os.path.exists('flag.txt') == False:
        print('首次启动')
        flag = open('flag.txt', 'w+')
        flag.write('1')
        flag.close()  # 关闭文件
        init()  # 初始化资源
        print_login_menu()  # 打印登录菜单
        user_select()  # 选择用户
    else:
        flag = open('flag.txt', 'r')
        word = flag.read()
        if len(word) == 1:
            init()  # 初始化资源
            print_login_menu()  # 打印登录菜单
            user_select()  # 选择用户


# 初始化管理员
def init():
    if os.path.exists('users') == False:
        file = open('u_root.txt', 'w')  # 创建并打开管理员账户文件
        root = {'rnum': 'root', 'rpwd': "123456"}
        file.write(str(root))  # 写入管理员信息
        file.close()  # 关闭管理员账户文件

        os.mkdir('users')  # 创建普通用户文件夹
        # else:


# 打印登录菜单
def print_login_menu():
    print('----用户登录----')
    print('1-管理员登陆')
    print('2-普通用户登陆')
    print('--------------')


# 用户选择
def user_select():
    while True:
        user_type_select = input('请选择用户类型')
        if user_type_select == '1':  # 管理员登陆验证
            root_login()
            break
        elif user_type_select == '2':  # 普通用户
            while True:
                select = input('是否需要注册?(y/n):')
                if select == 'y' or select == 'Y':
                    print('----用户注册----')
                    user_register()  # 用户注册
                    break
                elif select == 'n' or select == 'N':
                    print('----用户登录----')
                    break
                else:
                    print('输入有误,请重新选择')
            user_login()  # 用户登录
            break
        else:
            print('输入有误,请重新选择')


# 管理员登陆
def root_login():
    while True:
        print('****管理员登陆****')
        root_number = input('请输入账户名:')
        root_password = input('请输入密码:')
        file_root = open('u_root.txt', 'r')  # 只读打开文件
        root = eval(file_root.read())  # 读取账户信息
        # 信息匹配
        if root_number == root['rnum'] and root_password == root['rpwd']:
            print('登陆成功!')
            break
        else:
            print('验证失败')


# 用户注册
def user_register():
    user_id = input('请输入账户名:')
    user_pwd = input('请输入密码:')
    user_name = input('请输入昵称:')
    user = {'u_id': user_id, 'u_pwd': user_pwd, 'u_name': user_name}
    user_path = "./users/" + user_id
    file_user = open(user_path, 'w')  # 创建用户文件
    file_user.write(str(user))  # 写入
    file_user.close()  # 保存关闭


# 普通用户登录
def user_login():
    while True:
        print('****普通用户登录****')
        user_id = input('请输入账户名')
        user_pwd = input('请输入密码:')
        # 获取user目录中所有的文件名
        user_list = os.listdir('./users')  # 遍历元组,判断user_id是否在元组中
        flag = 0
        for user in user_list:
            if user == user_id:
                flag = 1
                print('登录中····')
                # 打开文件
                file_name = './users/' + user_id
                file_user = open(file_name)
                # 获取文件内容
                user_info = eval(file_user.read())
                if user_pwd == user_info['u_pwd']:
                    print('登录成功!')
                    break
        if flag == 1:
            break
        elif flag == 0:
            print('查无此人!请先注册用户')
            break


if __name__ == '__main__':
    is_first_start()

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值