面向對象之選課系統
阿新 • • 發佈:2019-03-02
文件 NPU 情況 屬性 新的 ati erro brush light
import os import sys import pickle student_info = ‘student_info‘ course_info = ‘course_info‘ userinfo = ‘userinfo‘ class Base: def __str__(self): return self.name class Course(Base): def __init__(self,name,price,period,teacher): self.name = name self.price = price self.period = period self.teacher = teacher def __repr__(self): return ‘ ‘.join([self.name, self.price, self.period, self.teacher]) class Person: @staticmethod def get_from_pickle(path): with open(path,‘rb‘) as f: while True: try : stu_obj = pickle.load(f) yield stu_obj #防止全部讀出、內存消耗過大 生成器 except EOFError: break def show_courses(self): for count,course in enumerate(self.get_from_pickle(course_info),1): print(count,repr(course)) def dump_obj(self,path,obj): with open(path,‘ab‘) as f: pickle.dump(obj,f) class Student(Person,Base): operate_lst = [ (‘查看所有課程‘, ‘show_courses‘), (‘選擇課程‘, ‘select_course‘), (‘查看已選課程‘, ‘check_selected_course‘), (‘退出‘, ‘exit‘)] def __init__(self,name): self.name = name self.courses = [] def __repr__(self): # course_name = [course.name for course in self.courses] course_name = [str(course) for course in self.courses] return ‘%s %s‘%(self.name,‘所選課程%s‘ % ‘|‘.join(course_name)) def select_course(self): self.show_courses() num = int(input(‘num >>>‘)) for count,course in enumerate(self.get_from_pickle(course_info),1): if count == num: self.courses.append(course) print(‘您選擇了%s課程‘ % (course)) break else:print(‘沒有您要找的課程‘) def check_selected_course(self): for course in self.courses: print(course.name,course.teacher) def exit(self): #避免頻繁操作文件 退出之前一次修改 with open(student_info+‘_bak‘, ‘wb‘) as f2: for stu in self.get_from_pickle(student_info): if stu.name == self.name: # 如果從原文件找到了學生對象和我當前的對象是一個名字,就認為是一個人 pickle.dump(self, f2) # 應該把現在新的學生對象寫到文件中 else: pickle.dump(stu, f2) # 反之,應該原封不動的把學生對象寫回f2 os.remove(student_info) os.rename(student_info+‘_bak‘,student_info) exit() @classmethod #類方法 def init(cls,name): for stu in cls.get_from_pickle(student_info): if stu.name == name: return stu else:print(‘沒有這個學生‘) class Manager(Person): operate_lst = [(‘創建課程‘,‘create_course‘), (‘創建學生‘,‘create_student‘), (‘查看所有課程‘,‘show_courses‘), (‘查看所有學生‘,‘show_students‘), (‘查看所有學生的選課情況‘,‘show_student_course‘), (‘退出‘,‘exit‘)] def __init__(self,name): self.name = name def create_course(self): name = input(‘course name : ‘) price = input(‘course price : ‘) period = input(‘course period : ‘) teacher = input(‘course teacher : ‘) course_obj = Course(name,price,period,teacher) self.dump_obj(course_info, course_obj) #調用父類Person的方法 (問題:未判斷,創建的該對象是否存在) print(‘%s課程創建成功‘%course_obj.name) def create_student(self): # 用戶名和密碼記錄到userinfo文件,將學生對象存儲在student_info文件 stu_name =input(‘student name : ‘) stu_pwd =input(‘student password : ‘) stu_auth = ‘%s|%s|Student\n‘%(stu_name,stu_pwd) stu_obj = Student(stu_name) with open(userinfo,‘a‘,encoding=‘utf-8‘) as f: f.write(stu_auth) #存入userinfo表 self.dump_obj(student_info, stu_obj) #調用父類Person的方法 (問題:未判斷,創建的該對象是否存在) print(‘%s學生創建成功‘%stu_obj.name) def show_students(self): for count,stu in enumerate(self.get_from_pickle(student_info),1): print(count,stu) #Student類的實例對象 print() 會按照 繼承類Base __str__的格式輸出 def show_student_course(self): for stu in self.get_from_pickle(student_info): print(repr(stu)) #Student類的實例對象 print() 會按照 __repr__的格式輸入 # print(stu) 默認是Student類的實例對象 print() 會按照 繼承類Base __str__的格式輸出 def exit(self): exit() @classmethod #類方法 def init(cls,name): return cls(name) # 管理員的對象 返回管理員實例對象 def login(): name = input(‘username : ‘) pawd = input(‘password : ‘) with open(userinfo,encoding=‘utf-8‘) as f: for line in f: usr,pwd,identify = line.strip().split(‘|‘) if usr == name and pawd == pwd: return {‘result‘:True,‘name‘:name,‘id‘:identify} else: return {‘result‘:False,‘name‘:name} ret = login() if ret[‘result‘]: print(‘\033[1;32;40m登錄成功\033[0m‘)#sys.modules[__name__]有時我們需要將一個文件的信息(類、函數及變量)保存到文件,我們不能直接保存函數對象,而是將其轉化為fn.__name__ if hasattr(sys.modules[__name__],ret[‘id‘]): # hasattr(object, name) 判斷一個對象裏面是否有name屬性或者name方法,返回BOOL值,有name特性返回True, 否則返回False。 cls = getattr(sys.modules[__name__],ret[‘id‘])#getattr(object, name[,default])獲取對象object的屬性或者方法,如果存在打印出來,如果不存在,打印出默認值,默認值可選。需要註意的是,如果是返回的對象的方法,返回的是方法的內存地址,如果需要運行這個方法,可以在後面添加一對括號。 obj = cls.init(ret[‘name‘]) # 實例化 獲取實例對象進行以下對象方法的操作 while True: for id,item in enumerate(cls.operate_lst,1): #索引id以數字1開始計算 print(id,item[0]) func_str = cls.operate_lst[int(input(‘>>>‘)) - 1][1] print(func_str) if hasattr(obj,func_str): getattr(obj,func_str)() else: print(‘登錄失敗‘)
面向對象之選課系統