Python实现电话簿工具(代码分享)
By qianghaohao(CodeNutter)
最近学了下python,用python实现了一个电话簿工具,主要实现思路是:通过字典来存储
电话簿信息,以姓名作为主键,以联系人对象作为值存储,最后保存的时候通过python标准
库提供的cPickile模块将字典序列化到文件,读取的时候直接加载字典即可。本程序比较简单
,整个程序只有一个类:Contacts类,代表联系人。初学,拿来练练手了!值得一提的是2.7.x
版本的编码的问题,要么出现编码异常,要么就是乱码,主要原因是2.7.x中默认是ascii编码,
这个问题比较复杂,不过遵循一定的规则编写可以很好地避免这类问题。有时间了专门写一篇
文章介绍如何解决python中中文编码的问题!不过python 3.x似乎不用管这类问题,可以直接
使用中文。
本程序主要功能如下:
源码:
# !/usr/bin/python
# -*- coding:utf-8 -*-
# Filename: phonebook.py
# Author: qianghaohao(CodeNutter)
# Email: codenutter@foxmail.com
# ------------------------------------编码问题------------------------------------
# import sys
# import locale
# print sys.getdefaultencoding() # 系统的缺省编码(一般就是ascii)
# print locale.getdefaultlocale() # 系统当前的编码
# print locale.getlocale() # 系统代码中临时被更改的编码
# print sys.getfilesystemencoding() # 文件系统编码
# print sys.stdin.encoding # 终端输入编码
# print sys.stdout.encoding # 终端输出编码
# # 代码缺省编码 :文件头 # -*- conding: utf-8 -*-
# --------------------------------------------------------------------------------
# 在python中内部编码是unicode,因此当前编码要先转换成unicode,然后再由unicode
# 转换成你需要的编码. 转换通过encode和decode函数,unicode相当于中间编码.
# decode encode
# str-------------->unicode-------------->str1
#---------------------------------------------------------------------------------
import sys
import os
import cPickle
import locale
# 联系人类--->最终联系人都是以此类的对象保存的,也就是对象序列化保存
class Contacts:
def __init__(self, name, tel, sex, email, address, birth):
self.name = name
self.tel = tel
self.sex = sex
self.email = email
self.address = address
self.birth = birth
def GetContactsInfo(self):
print U'姓名:%s' % (self.name).decode('utf-8') # 将utf-8转成Unicode输出,避免错误
print U'电话:%s' % (self.tel).decode('utf-8')
print U'性别:%s' % (self.tel).decode('utf-8')
print U'邮件:%s' % (self.email).decode('utf-8')
print U'地址:%s' % (self.address).decode('utf-8')
print U'出生日期:%s' % (self.birth).decode('utf-8')
def SetName(self, name):
self.name = name
def SetTel(self, tel):
self.tel = tel
def SetSex(self, sex):
self.sex = sex
def SetMail(self, mail):
self.mail = mail
def SetAddress(self, address):
self.address = address
def SetBirth(self, birth):
self.birth = birth
#----------------------------------------------------------------------------------------
# 封装自己的raw_input函数,避免重复的代码,为了保持很好的兼容性,先将提示串decode成unicode
# 然后再encode成和终端一样的编码,如果不这样做就会出现字符串的编码和终端编码不一致的状况,从而
# 导致乱码问题的出现。然后将raw_input函数的返回值再次decode成unicode,注意此时参数是stdin的
# 的编码,之所以这么做是因为stdin的编码不一定和python文本的编码一致,所以先转换成unicode,再
# 由unicode编码encode成utf-8编码,这样就保证了输入的字符串的编码和python源文件的编码一致了。
# ---------->这样做好绕...没办法,2.7.x就这样,也许还有其他解决方案,我先这么写.要是linux下
# 就没这么麻烦了...
#-----------------------------------------------------------------------------------------
def MyRawInput(prompt):
return raw_input(prompt.decode('utf-8').encode(sys.stdout.encoding)).decode(sys.stdin.encoding).encode('utf-8')
def ShowMenu():
print U'''
***************欢迎使用phonebook电话簿工具******************
1. 添加联系人
2. 删除联系人
3. 查找联系人
4. 编辑联系人
5. 显示所有联系人信息
6. 清空所有联系人
7. 帮助菜单
8. 保存电话簿
9. 退出系统
***************************************************************
'''
def EditMenu():
print U'''
----------------编辑选项-----------------
a. 编辑姓名
b. 编辑电话
c. 编辑性别
d. 编辑邮件
e. 编辑地址
f. 编辑出生日期
g. 调出菜单
h. 退出编辑
-----------------------------------------
'''
def GetHelp():
print U'''
GNU phonebook 1.0
By qianghaohao(CodeNutter)
Usage: phonebook [OPTION]... [FILENAME]...
--open 打开或新建电话簿
--version 版本信息
--help 使用帮助
'''
if (len(sys.argv) < 2):
print 'phonebook: missing OPTION'
print 'Usage: phonebook [OPTION]... [FILENAME]...'
print
print "Try 'phonebook --help' for more options"
sys.exit()
if sys.argv[1].startswith('--'):
option = sys.argv[1][2:]
if option == 'version':
print 'phonebook: Version 1.0'
elif option == 'help':
GetHelp()
elif option == 'open':
if len(sys.argv) < 3:
print '''
phonebook: missing FILENAME
Usage: phonebook [OPTION]... [FILENAME]...
'''
sys.exit()
filename = sys.argv[2]
try:
if os.path.exists(filename): # 如果电话簿文件存在,则加载到phonebook字典
f = file(filename)
phonebook = cPickle.load(f)
else: # 电话簿不存在则新建电话簿
phonebook = {}
except EOFError: # 如果文件为空,则加载失败,抛出异常,在此捕获异常并新建空字典
phonebook = {}
ShowMenu()
while True:
choice = MyRawInput('请输入您的选择(1-9)输入7可以调出帮助菜单:')
if choice == '1':
name = MyRawInput('姓名:')
tel = MyRawInput('电话:')
sex = MyRawInput('性别:')
mail = MyRawInput('邮件:')
address = MyRawInput('地址:')
birthday = MyRawInput('出生日期:')
phonebook[name] = Contacts(name, tel, sex, mail, address, birthday)
elif choice == '2':
name_to_del = MyRawInput('请输入要删除人的姓名:')
if phonebook.has_key(name_to_del):
del phonebook[name_to_del]
print U'联系人: %s 删除成功!' % name_to_del.decode('utf-8')
else:
print U'您要删的联系人:<%s> 不存在!' % name_to_del.decode('utf-8')
elif choice == '3':
name_to_find = MyRawInput('请输入要查找人的姓名:')
if phonebook.has_key(name_to_find):
phonebook[name_to_find].GetContactsInfo()
else:
print U'您要查找的联系人:<%s>不存在!' % name_to_find.decode('utf-8')
elif choice == '4':
name_to_modify = MyRawInput('请输入要编辑人的姓名:')
if phonebook.has_key(name_to_modify):
print U'===========您要编辑的联系人信息如下===========:'
phonebook[name_to_modify].GetContactsInfo()
EditMenu()
else:
print U'您要编辑的联系人:<%s>不存在!' % name_to_modify.decode('utf-8')
continue
while True:
to_modify_potion = MyRawInput('请输入您要编辑的选项(a-h)输入g调出菜单:')
if to_modify_potion == 'a':
new_name = MyRawInput('请输入新名字:')
phonebook[name_to_modify].SetName(new_name)
elif to_modify_potion == 'b':
new_tel = MyRawInput('请输入新电话:')
phonebook[name_to_modify].SetTel(new_tel)
elif to_modify_potion == 'c':
new_sex = MyRawInput('请输入新性别:')
phonebook[name_to_modify].SetSex(new_sex)
elif to_modify_potion == 'd':
new_mail = MyRawInput('请输入新邮件:')
phonebook[name_to_modify].SetMail(new_mail)
elif to_modify_potion == 'e':
new_addres = MyRawInput('请输入新地址:')
phonebook[name_to_modify].SetAddress(new_addres)
elif to_modify_potion == 'f':
new_birthday = MyRawInput('请输入新出生日期:')
phonebook[name_to_modify].SetBirth(new_birthday)
elif to_modify_potion == 'g':
EditMenu()
elif to_modify_potion == 'h':
break
else:
print U'输入错误,请重新输入(a-h)!'
elif choice == '5':
print U'===============所有联系人=============='
for name, contacts in phonebook.items():
contacts.GetContactsInfo()
print '---------------------------------------'
elif choice == '6':
phonebook.clear()
elif choice == '7':
ShowMenu()
elif choice == '8':
f = file(filename, 'w')
cPickle.dump(phonebook, f) # 存储电话簿到文件
f.close()
print U'''\n电话簿已保存,注意您的电话簿路径为: %s''' % (os.path.abspath(filename)).decode('utf-8')
elif choice == '9':
sys.exit()
else:
print U'请输入正确的选择(1-9)!'
else:
print 'Unknown option!'
print "Try 'phonebook --help' for more options"
sys.exit()
else:
print '''
The option must start with '--'
Example: phonebook --open filename
print "Try 'phonebook --help' for more information."
'''
sys.exit()