赞
踩
"为何表情,要让这世界安排?"
诶,我们也对python的一些基础语法有了一定能的了解了。并且在这基础上,学习了python中的文件操作,那么有了这些东西以后啊,我们能做什么呢?或许对很多数据结构的初学者来说,通讯录是他们第一个可以展示他们所习得知识的舞台。那么python中的通讯录,是怎样实现的呢?
python属于是一种半编译半解释的语言,没有严格的main函数。但是,我们写C/C++,Java等语言写一个程序时,第一步往往都是是实现好一个main函数,因为那是程序启动的"入口"。
- def menu():
- print("1> Add a new students's information ")
- print("2> Delete a existed Students' information ")
- print("3> Show all of information ")
- print("4> Find a Stduent ")
- print("0> For exit the Use ")
- choice = input("Please Enter your choice for Execute> ")
- return choice
-
-
- def main():
- print('----------------------------------')
- print(' 欢迎来到学生管理系统 ')
- print('----------------------------------')
- #打印菜单信息
- while True:
- choice = menu()
- if choice == '1':
- #add
- pass
- elif choice =='2':
- #delete
- pass
- elif choice =='3':
- #show
- pass
- elif choice =='4':
- #find
- pass
- elif choice =='0':
- #exit process
- print("Students'management System close done!")
- else:
- #输入错误
- print("Wrong Input,Please Try Again~")
我们设计3个通讯录的主功能,"增删查"。每个功能的pass是为了现在编译能过,没啥实际意义。
我们需要为通讯录做一份协议,即学生信息的格式。
- Students = []
- def Insert():
- print("Now for Add Students' information")
- # 姓名 学号 性别 院系
- student_id = input("Please Enter information for ID")
- student_name = input("Please Enter information for st_name")
- student_sexy = input("Please Enter information for sexy")
- student_faculty = input("Please Enter information for faculty")
-
- #差错处理
- if student_sexy not in ('男','女'):
- print("Wrong Input in Student_Sexy")
- return
-
- #收集信息,整合成一个字典类型{}
- student = {
- 'student_id':student_id,
- 'student_name':student_name,
- 'student_sexy':student_sexy,
- 'student_faculty':student_faculty
- }
-
- #存入students
- #如果要使用全局变量 最好先声明 再使用
- global Students
- Students.append(student)
- print("Success in Saving information")
用C语言完成通讯录时,为了保证其的动态性~我们选择使用一块动态内存开辟的空间。
如:Data_Block,而里面的数据 或许是一个struct st_Info{ .... }Data_Block[st_Info]。在pyhton中,似乎不需要像C语言管理数据的数组一样,像heap申请内存空间。而是用列表[](类似数组一样),但是它是动态开辟的,可以存储任何数据类型。如我们使用的全局边Students = []。每个student是一个哈希结构的字典,key:value(当然为什么这里选择字典结构呢?后面会提及)。因此,在python中,这里实现的存储学生信息的容器从动态数组(Data_Block)变为了列表(Students),从struct结构体(st_Info)变为了字典结构(student)。
第十一行的差错处理是有必要的,str1 not in('c1','c2'),是python特有的表达方式,是让str1去由('c1','c2')构成的列表序列查找,如果存在返回True,否则返回False。
- def Delete():
- #这里删除我们 选择根据student_id删除
- StudentID = input("Please Enter st_ID you wanner to delete")
- for s in Students:
- if s['student_id'] == StudentID:
- Students.remove(s)
- print("Sucess in deleting Information")
这里的s会在Students这个序列里去取里面的每个对象。这里我们设计的字典结构的原因找到了,我们可以很轻松地甄别到哪个s才是 要被删除的。
列表.remove(obj):指的是在列表中删除obj元素。
打印格式,我们希望[姓名] \t [学号] \t [性别]\t [院系]\t
- def Show():
- for info in Students:
- print(f"[{info['student_name']}]\t[{info['student_id']}]\t[{info['student_gender']}]\t{info['student_faculty']}")
- print(f"Show the number of Information:{len(Students)}")
-
-
- def Find():
- #我们这里输入姓名查找因此 不免会有同名的现象。我们统一做的处理是打印出出来
- count = 0
- name = input("Please Enter Name you wanner to find> ")
- for info in Students:
- if name == info['student_name']:
- print(f"[{info['student_id']}]\t[{info['student_name']}]\t[{info['student_gender']}]\t,[{info['student_faculty']}]")
- count += 1
- print(f"Total of the Students: {count}")
那么我们的增删查实现的功能也完成了,我们来看看成果吧~
此时我们的系统还存有两个人的信息,我们重新打开程序试试看。
我们发现没有任何数据??? 那么之前辛辛苦苦插入的数据去哪里了呢?我们都知道,程序一旦运行起来,OS通过调度将程序的代码读进内存,以供cpu快速取指令执行任务。一旦程序结束,那么本来该分配给程序的空间,也就被"销毁"。你运行时存储的数据,无非是在内存中存储的,是易失性的。
那么什么数据是永久存储的呢?答案当然是磁盘!
我们想要的存入记事本的格式是这样的,以便读取。
- def Save():
- #将我们的数据存入磁盘
- with open('DataSave.txt','w',encoding = 'utf-8') as f :
- #写入文件
- for info in Students:
- f.wirte(f"{info['student_name']}\t{info['student_id']}\t{info['student_gender']}\t{info['student_faculty']}\n")
-
- print(f"Total for Save: {len(Students)}")
with open上下文管理器,等于说我们可以不需要手动管理想系统申请的文件描述符,它会帮我们进行资源的回收管理。
有了save,那么一定有从磁盘文件中读取数据的步骤:
- def Load():
- #有没有可能 我是第一次打开更新这个管理系统?那么就不会存在DataSave.txt
- if not os.path.exists('DataSave.txt.'):
- print("Nothing to Load")
- return #也就不需要读取了
-
- count = 0
- global Students
- #读文件
- with open('DataSave.txt','r',encoding='utf-8') as f:
- # 因为我们是按照行存储的 那么读取数据也是按照行读取
- for line in f:
- #name id gender faculty\n
- line = line.strip() #去掉传末尾\n
- tokens = line.split('\t')#以'\t'作为分隔符 切割字符串
- #解析出来的格式一定有四个(name,id,gender,faculty)
- if len(tokens) != 4:
- print("Wrong Parse format!")
- return
- #填充信息
- student = {
- 'student_name':tokens[0],
- 'student_id':tokens[1],
- 'student_gender':tokens[2],
- 'student_faculty':tokens[3]
- }
- #插入总的序列容器中
- Students.append(student)
- count += 1
- print(f"Total Load num: {count}")
我们需要在程序加载处Load之前存储的数据。
我们首先清空记事本,开是我们的录用信息之旅吧~
如我们所见,我们存入的信息能在磁盘上保存了。
当然怎么退出我们的通讯录呢,我想点最上面的红色方括号有些挫。系统sys提供了结束进程的函数,调用即可。
其实可以看见,如果你写过一套完整的纯C写的通讯录,你就会发现后发展起来的语言,对于前者的一些不好地方的舍弃,好的地方的取用。我们在python中用可以存储任何数据类型、自动扩容的列表,替代了需要动态开辟的数组。我们用python的字典,替代了需要在.h中定义的strcut st_Info{}。我们可以使用line = str.split('\t'),以'\t'分割切开,返回一个列表赋值给line,我们同样使用str.strip()去掉字符串末尾与数据读取无关紧要字符…… 只能说,"Life is short,you need Python"。
本篇就到此结束了,感谢你的阅读。
祝你好运,向阳而生~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。