类与对象,文件操作,生成器理解

概念

面向对象编程:定义一大类对象都有的通用行为,用一个类去解决大类对象的不同问题。如果说根据不同的实际情况编写不同的代码是编程的一种思路,那么编写出一种代码解决不同的实际问题就是面向对象的编程思路。

实战

任务目标:
制作一个简易的学员管理系统,实现增加学员信息,删除学员信息
存储的信息为:学号(唯一),姓名,性别,年龄,爱好
需求:
1、使用面向对象的方式来完成
2、以txt文件方式来存储学员信息
students.txt
提示:删除信息可以根据id删除

python代码

import os


class Students_Manage():
    def __init__(self):  # __init__下的代码会在创建对象时自动执行
        '''自动创建txt文件'''
        if not os.path.exists('students.txt'):  # 判断是否存在学生文件,如果不存在自动创建
            with open('students.txt', 'w', encoding='utf-8') as f:  # 创建文件,并写入标题行
                f.write('id\tname\tsex\tage\tlove\n')

    def add_student(self, id, name, sex, age, love):  # 需要传入学生参数
        '''添加学员'''
        try:  # 查看是否已经存在相同id的学员,如果存在不允许添加
            st = self.index_student(id)
            id_student = st.__next__()
            print(f'ID为:{id}的学员已存在')
            print(id_student)
        except StopIteration:  # 如果学员不存在会导致迭代器报错,则捕获并执行添加学员
            with open('students.txt', 'a', encoding='utf-8') as f:
                f.write(f'{id}\t{name}\t{sex}\t{age}\t{love}\n')
                print('学员添加成功')

    def delete_student(self, id):  # 需要传入id,根据id删除数据项
        '''删除学员'''
        try:  # 找到该id的学生所在行
            st = self.index_student(id)  # 调用index_student
            st.__next__()
            row = st.__next__()
        except StopIteration:  # 若没有找到则直接返回
            print(f"没有id为:{id}的学生")
            return 0

        try:  # 尝试删除下方需要的临时文件
            os.remove('new_students.txt')
        except FileNotFoundError:  # 如果没找到文件那么什么也不用做
            pass

        all = self.all_students()
        all.__next__()
        content = all.__next__()  # 调用all_student把学生文件中的所有内容传入content列表
        del content[row]  # 删除id所在那一行的数据项
        for i in content:  # 删除id所在行之后遍历每一行,并以追加的方式追加写入临时文件new_students.txt
            with open('new_students.txt', 'a', encoding='utf-8') as f:
                f.write(str(i))  # 一行一行写入
        os.remove('students.txt')  # 删除旧的students.txt文件
        os.rename('new_students.txt', 'students.txt')  # 将临时文件重命名为students.txt文件
        print('删除成功')  # 执行到这里删除操作完成


    def index_student(self, id):
        '''查询某个id的学员'''
        Whether_find = 0  # 使用Whether_find变量,记录是否找到该id的学生
        all = self.all_students()
        all.__next__()
        content = all.__next__()  # 调用all_student将students文件中的所有内容按行传入content列表
        row = 0  # 从第零行开始遍历
        for i in content:
            student_detial = i.split('\t')  # 用split以’\t‘分割
            if id == student_detial[0]:  # 判断一行的第零个元素(即id) 是否是要删除的学生id
                Whether_find = 1  # 找到将记录改为1
                yield student_detial  # 使用生成器的方式返回学生详情,以便用户查看
                yield row  # 使用yield返回所在行号,以便delete_student使用
            else:
                row += 1
        '''生成器的return如何接收?'''
        if Whether_find == 1:
            return True  # 如果找到,在第3次使用next方法则会抛出异常StopIteration:True
        else:
            return False  # 没找到,在第1次使用next方法则会抛出异常StopIteration:False
        '''接收不了,无意义'''


    def all_students(self):
        '''查看所有学员'''
        with open('students.txt', 'r', encoding='utf-8') as f:
            content = f.read()
            f.seek(0)  # 需要将光标置于首位,否则接下来什么也读取不到
            content_list = f.readlines()
            # yield content  # 返回所有内容以便用户查看
            # yield content_list  # 返回列表形式以便其他函数使用
            # print('程序没有直接终止')
            # return 0
            '''上四行注释代码不能写在with open里面,因为在外部调用.__next__方法会导致这个函数程序阻塞或直接终止,无法自动关闭文件'''
        yield content  # 返回所有内容以便用户查看
        yield content_list  # 返回列表形式以便其他函数使用
        return 0


    def __str__(self):
        return "感谢使用本系统,欢迎下次光临!"

    def main(self):
        while True:
            print('增加学员:1\t删除学员:2\t查看某个学员:3\t查看所有学员:4\t退出:5')
            while True:
                try:  # 捕获用户违法输入错误
                    num = int(input('请输入数字选择功能:'))
                    break
                except ValueError:
                    print('您的输入有误,请重新输入!')
            if 1 == num:
                id = input('请输入学员id:')
                name = input('请输入学员name:')
                sex = input('请输入学员sex:')
                age = input('请输入学员age:')
                love = input('请输入学员love:')
                self.add_student(id=id, name=name, sex=sex, age=age, love=love)
            elif 2 == num:
                id = input('请输入学员id:')
                self.delete_student(id)
            elif 3 == num:
                try:
                    id = input('请输入学员id:')
                    print(self.index_student(id).__next__())  # 寻找该id的学员
                except StopIteration:  # 没有找到则会报错StopIteration
                    print(f"没有id为:{id}的学生")
            elif 4 == num:
                all=self.all_students()
                print(all.__next__())
            elif 5 == num:
                break
            else:  # 捕获用户违法输入错误
                print('您的输入有误,请重新输入!')


students = Students_Manage()

if __name__ == '__main__':
    students.main()
    print(students)

知识点

  1. 使用class创建类
  2. 使用类创建对象
  3. 类中__init__中的代码会在创建对象时自动执行,也可以在__init__中定义类的属性,给类传参
  4. 类方法的定义
  5. 类的返回值__str__
  6. 迭代器与生成器相关知识点
  7. 生成器中return含义
  8. yield导致程序阻塞或直接终止,代码第83行,65行
  9. 使用open进行文件操作
  10. os模块相关文件操作
  11. name == 'main’程序入口,只会在当前python文件执行的代码,无法被调用

关于生成器的一些测试

def te():
   if False:
   	yield 1
   if False:
   	yield 2
   if True:
   	print('我会执行1',end='\t')
   	yield 1
   	print('我会执行1.1')
   i = 1
   while i<=2:
   	yield '循环内'
   	print('我会执行2')
   	i+=1

   print('强制执行3')
   return 666  # stopIteration: (value)


it=te()
print(it.__next__(),end='\t')
print(it.__next__(),end='\t')
print(it.__next__(),end='\t')
#print(it.__next__())  # 强制多使用一次next方法,执行后续代码

你可能感兴趣的:(从零开始的python生活,python)