Python基础 2.1 文件操作

2.1 文件


​ 文件是为了持久化存储数据,有很多种类型的文件。内存存储的数据在断电之后会丢失,所以必须要有文件来存储。

2.1.1 文件的打开和关闭

1.文件的操作流程

1.打开文件,或者建立文件

2.读写数据

3.关闭文件

2.打开文件

我们可以使用内置的open函数,打开或者创建一个文件。

文件变量 = open(文件名,访问模式)

f = open('xxx.txt', 'w',encoding = "UTF-8" )

2个简单的访问模式说明,后面还有更多模式。

访问模式说明
r只用于读取,默认模式。文件不存在的话会报错。
w只用于写入,文件存在则先清空文件内容,文件不存在则创建新文件。

encoding指的是文件编码,我们Windows下的python环境默认是GBK,可能会导致乱码,记得转成UTF-8

2.关闭文件

文件变量.close()

​ 如果程序结束程序也会自动打开的文件,但是一般情况下不会自动结束程序。

只有关闭了文件,文件内容才能真正写进去。

3.自动关闭文件(记忆)

with open("xxx.txt", "w") as f:
    pass

2.1.2 文件的读写操作

1.文件的写操作

f = open("xxx.txt", "w")
f.write('str')
f.write('str2')
f.close()
#如果不执行close的时候是不会保存的

2.文件的读操作

1.按字符量读取
内容变量 = 文件变量.read(n)

n为读取的字符数,不设置则为全部读取。每次读取会移动一次光标,一次读取操作后光标不会重置回前面去,再次执行读操作会从当前光标开始读取。

2.全行读取
内容变量 = 文件变量.readlines(n)

会把每行读取成一个字符串,作为一个元素,存放到列表里,且会读取到换行符。

3. 按行读取
内容变量 = 文件变量.readline()

一次读取一行,也包含换行符。

3.文件的访问模式详解

访问模式说明
r只用于读,默认模式,如文件不存在会报错。
w只用于写,文件存在则清空文件内容,文件不存在则创建新文件。
a只用与写,文件存在则追加内容,文件不存在则创建新文件。
r+用于读写,读是从文件开头读取,写从文件尾开始写入,写光标会跟随读光标移动,如果移动到开头,会覆盖前面的内容。文件不存在会报错
w+用于读写,文件存在则清空文件内容,文件不存在则创建新文件。写从文件尾开始写入,写光标会跟随读光标移动,如果移动到开头,会覆盖前面的内容。
a+用于读写,文件存在则追写内容,文件不存在则创建新文件,写光标只会在最后。
rb二进制格式的只读操作。后续网络课程中具体讲解。
wb二进制格式的只写操作。后续网络课程中具体讲解。
ab二进制格式的追写操作。后续网络课程中具体讲解。

拓展知识f.seek()用来移动光标,但是一般移动的话只能移动到开头,想移动到具体的必须用二进制的读写方式。

4.文件的路径

1.绝对路径:

指文件完整的路径,是在硬盘上的路径。

​ 比如一个文件在

E:\Code\Pycode 但是我们写代码的时候,Windows下的路径必须改,\换成成\\,或者用引号括起来'E:/Code/Pycode'

但是正常情况下很少应用绝对路径,因为会导致转移到其他环境的时候无法运行,因为路径不一致。

2.相对路径:

指文件相对于自己的目标文件的位置,不是完整的。

比如当前文件夹下有一个1.txt,我们访问的时候可以直接写1.txt或者 ./1.txt

如果是上一级文件夹里的,则是../1.txt也就是2个点对应的是当前文件位置的上一级文件夹。

2.1.3 文件的备份操作

如果我们想备份一个大文件,是没法一次性读取所有内容的,会超出缓存,我们选择使用一个循环,一次读取一点同时写入一点,那么这样就可以备份所有的内容了。

def main():
    f_src = open(old_filename, "br")
    f_dst = open(new_filename, "bw")
    while True:
        ret = f_src.read(1024)
        if len(ret) == 0: 
''' 注意 因为要读取的是任意文件而不是文本文件,所以我们不能用普通的r和w,得用br和bw,同时因为二进制读取是不能用字符串的空来判断的,得改成b'',也就是二进制的空,或者我们得把判断换成长度是0,或者直接用if not ret: 没读到东西就为真,有就为假,最后的一种方法最为泛用'''
            break
        else:
            f_dst.write(ret)
    f_src.close()
    f_dst.close()


def new_filename(name_x):
    old_name = name_x
    index_sp = old_name.rfind('.')
    l_str = old_name[:index_sp]
    r_str = old_name[index_sp:]
    new_name = l_str + '(备份)' + r_str
    return new_name


old_filename = input("请输入要备份的文本名:")
new_filename = new_filename(old_filename)
main()

2.1.4 文件的操作(了解)

如果我们想对已有的文件进行操作,比如复制,粘贴,重命名之类的,我们需要用python内置的os模块,才能对系统内的文件进行操作。

import os
os.方法名()

1.文件重命名

os.rename("想改的文件名", "想更改后的文件名")

2.删除文件

os.remove("想删除的文件名")

3.创建文件夹

os.mkdir("文件夹名")

4.删除文件夹名

os.rmdir("文件夹名")

5.获取当前工作的绝对路径

work_path = os.getcwd()
print(work_path)

6.改变默认工作目录

os.chdir("../) 切换到上一级路径 

7.获取目录列表,获取当前目录或者指定目录的文件信息

temp_list = os.listdir() 不指定的话是默认当前目录

8.判断文件是否存在

ret = os.path.exists("1.txt")
print(ret)

2.1.5 批量修改文件名(应用)

import os
name_list = os.listdir('renameTest')
print(name_list)
# 生成renameTest文件夹里所有文件的名字列表
os.chdir('renameTest')
# 切换到renameTest文件夹
for name in name_list:
    new_name = "[黑马程序]-"+ name
    os.rename(name, new_name)
new_name_list = os.listdir()
print(new_name_list)

输出

['123.txt', 'Good 123.txt', 'rest.txt']
['[黑马程序]-123.txt', '[黑马程序]-Good 123.txt', '[黑马程序]-rest.txt']

2.1.5 字符串和容器类型相互转换

我们可以用str()讲一个列表转换成字符串,如下

user_list = [{'name': 'tom', 'age': 19, 'height': 1.78}, {'name': 'jerry', 'age': 25, 'height': 1.56},
             {'name': 'john', 'age': 17, 'height': 1.90}]
print(type(user_list))
str_list = str(user_list)
print(type(str_list), str_list)
<class 'list'>
<class 'str'> [{'name': 'tom', 'age': 19, 'height': 1.78}, {'name': 'jerry', 'age': 25, 'height': 1.56}, {'name': 'john', 'age': 17, 'height': 1.9}]

如果我们想将类似的字符串也给转回去。

new_list = eval(str_list)
print(type(new_list), new_list)
new_dict = new_list[0]
print(type(new_dict), new_dict)

输出

<class 'list'> [{'name': 'tom', 'age': 19, 'height': 1.78}, {'name': 'jerry', 'age': 25, 'height': 1.56}, {'name': 'john', 'age': 17, 'height': 1.9}]
<class 'dict'> {'name': 'tom', 'age': 19, 'height': 1.78}

2.1.6 应用 学生名片信息系统增添读取和保存文件的功能

import os

# 学生的列表应为全局变量,我们采用列表嵌套字典,用于保存用户信息


student_list = []
# 我们应该设置一个函数,在运行的时候默认加载一个配置文件。


def load_local():
    if os.path.exists("stu_list.config"):
        print("读取到默认文件")
        with open("stu_list.config", "r")as f:
            user_str_list = f.read()
            old_student_list = eval(user_str_list)
            print("档案已经读取")
            return old_student_list
    else:
        print("没有该文件,请重新选择配置文件读取")

# 制作一个保存学生信息到文件的功能,如果传参的话可以选择具体文件名


def save_file(file_name):
    if os.path.exists(file_name):
        print("原文件已经存在,是否覆盖?", end="")
        user_sw = input("(yes or no) ")
        if user_sw == 'no':
            return
        else:
            print("覆盖该文件")
    with open(file_name, "w") as f:
        user_str_list = str(student_list)
        f.write(user_str_list)
        print("学生信息已保存")


# 制作一个读取本地文件里学生信息的功能,如果传参的话可以选择具体文件名
def load_file(file_name):
    if os.path.exists(file_name):
        print("读取到该文件")
        with open(file_name, "r")as f:
            user_str_list = f.read()
            old_student_list = eval(user_str_list)
            print("档案已经读取")
            return old_student_list
    else:
        print("没有该文件,请重新输入")


# 主界面应为一个死循环,因为必须一直停留在当前页面选择,以下为主界面逻辑


def main():
    global student_list
    student_list = load_local()
    while True:
        menu_print()
        user_select = int(input("请输入需要选择的功能:"))
        if user_select == 1:
            print("添加学生信息")
            add_student()
        elif user_select == 2:
            print("查询所有学生信息")
            check_all_student()
        elif user_select == 3:
            print("查询指定学生信息")
            check_student()
        elif user_select == 4:
            print("编辑指定学生信息")
            edit_student()
        elif user_select == 5:
            print("删除指定学生信息")
            delete_student()
        elif user_select == 6:
            save_name = input("请输入要保存的文件名:")
            save_file(save_name)
        elif user_select == 7:
            load_name = input("请输入要读取的文件名:")
            student_list = load_file(load_name)
        elif user_select == 8:
            print("退出学生名片管理系统")
            break
        else:
            print("输入错误,请重新输入")


# 显示主界面菜单,菜单是每次选择选项并且完全选项内容后会重复出现的东西,那么我们可以给写成函数来重复调用
def menu_print():
    print("=" * 10, "学生名片管理系统", "=" * 10)
    print("1.添加学生信息")
    print("2.查询所有学生信息")
    print("3.查询指定学生信息")
    print("4.修改指定学生信息")
    print("5.删除指定学生信息")
    print("6.保存档案")
    print("7.读取档案")
    print("8.退出系统")
    print("=" * 40)


'''
开始做第一个选项的函数,先分清逻辑顺序
首先我们要输入3个内容,名字,年龄,电话
然后用for循环遍历查看里面有没有名字冲突的,如果有则添加失败并且提醒,用break跳出循环
如果没有则进入else添加用户字典到列表里
'''


def add_student():
    new_name = input("请输入学生的名称:")
    new_age = int(input("请输入学生的年龄:"))
    new_phone = input("请输入学生的电话号码:")
    for a, student_dict in enumerate(student_list):
        if student_dict['name'] == new_name:
            print("该学生已经存在系统,无需再次添加")
            break
    else:
        new_student = {'name': new_name, 'age': new_age, 'phone': new_phone}
        student_list.append(new_student)
        print("添加学生信息成功")


'''
实现查询所有学生信息的功能
我们直接用之前学的enumerate直接遍历所有即可,如果为空则跳出循环
提示系统目前没有任何学生信息
'''


def check_all_student():
    if not student_list:
        print("系统目前没有任何学生信息,请先添加学生信息")
    else:
        print("序号\t\t姓名\t\t年龄\t\t电话")
        for n, student_dict in enumerate(student_list):
            print('%d\t\t%s\t\t%d\t\t%s' % (n + 1, student_dict['name'], student_dict['age'], student_dict['phone']))


'''
实现查询指定学生的信息,
首先需要input来获取要查询学生的名字
然后遍历列表里的名字,如果没有则提示,有则显示内容
'''


def check_student():
    check_name = input("请输入要查询的学生名字:")
    for c, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (c + 1, student_dict['name'], student_dict['age'], student_dict['phone']))

            break
    else:
        print("学生档案里无此学生的相关信息,请重新确认")


'''
同样的,我们要实现修改指定学生的档案,也是要经过一次筛选,但是不用Break跳过循环,
而是重新输入数据进行更改
'''


def edit_student():
    check_name = input("请输入要修改的学生名字:")
    for e, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (e + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            edit_name = input("请输入要更改的学生名字:")
            edit_age = int(input("请输入要更改的学生年龄:"))
            edit_phone = input("请输入要更改的学生电话号码:")
            student_list[e] = {'name': edit_name, 'age': edit_age, 'phone': edit_phone}
            print("修改完成")
            break
    else:
        print("学生档案里无此学生的相关信息,请重新确认")


'''
删除指定的学生档案同理
'''


def delete_student():
    check_name = input("请输入要查询的学生名字:")
    for d, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (d + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            del student_list[d]
            print("已删除该学生的信息")
            break
    else:
        print("学生档案里无此学生的相关信息,请重新确认")


main()

# 字典输出问题,无法对齐提前打印的东西,格式化输出也不行,感觉需要一个表格才能限制,如果制表需要导入制表模块
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值