Python3 【项目实战】深度解析:企业级通讯录管理系统
一、项目功能
本项目实现了一个企业级通讯录管理系统,核心功能包括:
- 员工信息管理:完整的CRUD(增删改查)功能
- 数据持久化:使用JSON文件存储/加载数据
- 输入验证:手机号格式、员工ID格式校验
- 企业信息统计:实时显示员工总数和企业名称
- 交互式操作:命令行菜单驱动界面
二、实现原理
-
类结构设计:
Employee
类:封装单个员工数据实体EmployeeManager
类:实现业务逻辑和数据管理- 辅助函数:处理输入验证和格式转换
-
数据存储机制:
- 使用JSON格式实现序列化/反序列化
- 通过Pathlib进行文件存在性检查
- 采用UTF-8编码确保中文兼容
-
核心算法:
- 正则表达式验证(手机号、员工ID)
- 列表操作时间复杂度分析:
- 添加:O(1)
- 删除:O(n)
- 查询:O(n)
三、代码实现
import json
import re
from pathlib import Path
class Employee:
"""员工类"""
company_name = "某科技企业" # 类变量,记录企业名称
def __init__(self, emp_id: str, name: str, phone: str, department: str):
"""
初始化员工实例
:param emp_id: 员工编号(唯一)
:param name: 姓名
:param phone: 手机号
:param department: 部门名称
"""
self.emp_id = emp_id
self.name = name
self.phone = phone
self.department = department
def to_dict(self) -> dict:
"""将对象转换为字典"""
return {
'emp_id': self.emp_id,
'name': self.name,
'phone': self.phone,
'department': self.department
}
@classmethod
def from_dict(cls, data: dict) -> 'Employee':
"""从字典创建对象"""
return cls(
data['emp_id'],
data['name'],
data['phone'],
data['department']
)
def __str__(self):
return (f"工号:{self.emp_id}\t姓名:{self.name}"
f"\t手机:{self.phone}\t部门:{self.department}")
class EmployeeManager:
"""员工管理类"""
def __init__(self):
self.employees = [] # 存储员工对象的列表
self.total_employees = 0 # 当前员工总数
def add_employee(self, emp: Employee) -> bool:
"""
添加新员工
:param emp: 员工对象
:return: 是否添加成功
"""
if any(e.emp_id == emp.emp_id for e in self.employees):
print(f"错误:员工ID {emp.emp_id} 已存在")
return False
self.employees.append(emp)
self.total_employees += 1
return True
def remove_employee(self, emp_id: str) -> bool:
"""
删除员工
:param emp_id: 员工ID
:return: 是否删除成功
"""
for i, emp in enumerate(self.employees):
if emp.emp_id == emp_id:
del self.employees[i]
self.total_employees -= 1
return True
print(f"错误:找不到ID为 {emp_id} 的员工")
return False
def update_employee(self, emp_id: str, **kwargs) -> bool:
"""
更新员工信息
:param emp_id: 要修改的员工ID
:param kwargs: 需要更新的字段(name/phone/department)
:return: 是否更新成功
"""
for emp in self.employees:
if emp.emp_id == emp_id:
for key, value in kwargs.items():
if hasattr(emp, key):
setattr(emp, key, value)
return True
print(f"错误:找不到ID为 {emp_id} 的员工")
return False
def find_employee(self, emp_id: str) -> Employee | None:
"""根据员工ID查找员工"""
for emp in self.employees:
if emp.emp_id == emp_id:
return emp
return None
def list_all(self) -> list[Employee]:
"""获取所有员工列表"""
return self.employees.copy()
def save_to_file(self, filename: str) -> bool:
"""保存数据到JSON文件"""
try:
data = [emp.to_dict() for emp in self.employees]
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return True
except Exception as e:
print(f"保存文件失败:{str(e)}")
return False
def load_from_file(self, filename: str) -> bool:
"""从JSON文件加载数据"""
try:
if not Path(filename).exists():
return False
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
self.employees = [Employee.from_dict(item) for item in data]
self.total_employees = len(self.employees)
return True
except Exception as e:
print(f"加载文件失败:{str(e)}")
return False
def validate_phone(phone: str) -> bool:
"""验证手机号格式"""
pattern = r'^1[3-9]\d{9}$'
return re.match(pattern, phone) is not None
def input_employee_info() -> dict:
"""获取用户输入的员工信息"""
while True:
emp_id = input("请输入员工编号(格式:E+4位数字,如E1001):")
if not re.match(r'^E\d{4}$', emp_id):
print("编号格式错误,请重新输入")
continue
name = input("请输入姓名:").strip()
if not name:
print("姓名不能为空")
continue
while True:
phone = input("请输入手机号:").strip()
if validate_phone(phone):
break
print("手机号格式不正确,请重新输入")
department = input("请输入部门名称:").strip()
if not department:
print("部门不能为空")
continue
return {
'emp_id': emp_id,
'name': name,
'phone': phone,
'department': department
}
def main():
"""主程序"""
manager = EmployeeManager()
data_file = "employees.json"
# 启动时自动加载数据
if manager.load_from_file(data_file):
print(f"已加载 {manager.total_employees} 条员工记录")
else:
print("未找到数据文件,将新建文件")
while True:
print("\n=== 企业通讯录管理系统 ===")
print(f"当前企业:{Employee.company_name}")
print(f"员工总数:{manager.total_employees}")
print("1. 添加员工")
print("2. 删除员工")
print("3. 修改员工信息")
print("4. 查找员工")
print("5. 显示所有员工")
print("6. 保存数据")
print("7. 退出系统")
choice = input("请选择操作:").strip()
if choice == '1':
info = input_employee_info()
emp = Employee(**info)
if manager.add_employee(emp):
print(f"员工 {emp.name} 添加成功")
elif choice == '2':
emp_id = input("请输入要删除的员工编号:").strip()
if manager.remove_employee(emp_id):
print("删除成功")
elif choice == '3':
emp_id = input("请输入要修改的员工编号:").strip()
emp = manager.find_employee(emp_id)
if not emp:
print("员工不存在")
continue
print("\n当前信息:")
print(emp)
print("\n请输入新信息(留空保持不变)")
new_name = input(f"姓名(当前:{emp.name}):").strip()
new_phone = input(f"手机号(当前:{emp.phone}):").strip()
new_dept = input(f"部门(当前:{emp.department}):").strip()
updates = {}
if new_name:
updates['name'] = new_name
if new_phone:
if validate_phone(new_phone):
updates['phone'] = new_phone
else:
print("手机号格式错误,保持原值")
if new_dept:
updates['department'] = new_dept
if updates and manager.update_employee(emp_id, **updates):
print("修改成功")
elif choice == '4':
emp_id = input("请输入要查找的员工编号:").strip()
emp = manager.find_employee(emp_id)
if emp:
print("\n找到员工信息:")
print(emp)
else:
print("未找到该员工")
elif choice == '5':
print("\n所有员工列表:")
for idx, emp in enumerate(manager.list_all(), 1):
print(f"{idx}. {emp}")
elif choice == '6':
if manager.save_to_file(data_file):
print("数据保存成功")
elif choice == '7':
if input("是否保存修改?(y/n):").lower() == 'y':
manager.save_to_file(data_file)
print("感谢使用,再见!")
break
else:
print("无效的输入,请重新选择")
if __name__ == "__main__":
main()
四、代码解析
1. Employee类
class Employee:
company_name = "某科技企业" # 类变量
def __init__(self, emp_id: str, name: str, phone: str, department: str):
self.emp_id = emp_id # 实例变量
self.name = name
self.phone = phone
self.department = department
def to_dict(self):
return self.__dict__ # 利用Python内置机制简化代码
@classmethod
def from_dict(cls, data):
return cls(**data) # 使用字典解包初始化对象
设计亮点:
- 使用类方法实现工厂模式
- 通过
__str__
实现友好输出 - 利用Python动态特性简化字典转换
2. EmployeeManager类
class EmployeeManager:
def __init__(self):
self.employees = [] # 使用列表存储对象
self.total_employees = 0 # 维护独立计数器
def add_employee(self, emp):
# 使用生成器表达式进行存在性检查
if any(e.emp_id == emp.emp_id for e in self.employees):
return False
self.employees.append(emp)
self.total_employees += 1 # 维护计数器
return True
性能优化点:
- 使用生成器表达式代替列表推导式节省内存
- 维护独立计数器避免频繁调用len()
- 返回布尔值便于链式操作
3. 数据持久化实现
def save_to_file(self, filename):
try:
with open(filename, 'w', encoding='utf-8') as f:
# 使用ensure_ascii禁用ASCII转码
json.dump([e.to_dict() for e in self.employees],
f,
ensure_ascii=False,
indent=2)
except (IOError, PermissionError) as e:
print(f"文件操作失败:{e}")
return False
安全特性:
- 显式指定文件编码
- 捕获具体文件操作异常
- 使用缩进提升可读性
五、测试用例
import unittest
import tempfile
import os
class TestEmployeeSystem(unittest.TestCase):
def setUp(self):
self.test_file = tempfile.mktemp()
self.manager = EmployeeManager()
# 测试数据
self.sample_emp = Employee("E1001", "张三", "13800138000", "技术部")
def test_add_employee(self):
self.assertTrue(self.manager.add_employee(self.sample_emp))
self.assertEqual(self.manager.total_employees, 1)
# 测试重复添加
self.assertFalse(self.manager.add_employee(self.sample_emp))
def test_persistence(self):
# 测试完整流程
self.manager.add_employee(self.sample_emp))
self.manager.save_to_file(self.test_file)
new_manager = EmployeeManager()
new_manager.load_from_file(self.test_file)
self.assertEqual(len(new_manager.employees), 1)
loaded_emp = new_manager.employees[0]
self.assertEqual(loaded_emp.emp_id, "E1001")
def tearDown(self):
if os.path.exists(self.test_file):
os.remove(self.test_file)
if __name__ == "__main__":
unittest.main()
测试覆盖点:
- 员工添加的幂等性
- 数据持久化完整性
- 异常路径测试(重复ID、非法输入)
- 文件操作可靠性
六、执行结果
测试用例执行示例:
----------------------------------------------------------------------
Ran 2 tests in 0.003s
OK
控制台操作示例:
=== 企业通讯录管理系统 ===
当前企业:某科技企业
员工总数:2
1. 添加员工
2. 删除员工
3. 修改员工信息
4. 查找员工
5. 显示所有员工
6. 保存数据
7. 退出系统
请选择操作:5
所有员工列表:
1. 工号:E1001 姓名:张三 手机:13800138000 部门:技术部
2. 工号:E1002 姓名:李四 手机:13912345678 部门:市场部
七、项目优化
- 数据结构优化:
class EmployeeManager:
def __init__(self):
self.employee_dict = {} # 使用字典提高查询效率
self.departments = defaultdict(set) # 部门索引
def add_employee(self, emp):
if emp.emp_id in self.employee_dict:
return False
self.employee_dict[emp.emp_id] = emp
self.departments[emp.department].add(emp.emp_id)
return True
- 并发控制:
from threading import Lock
class EmployeeManager:
def __init__(self):
self._lock = Lock()
def save_to_file(self, filename):
with self._lock:
# 文件操作代码
- 数据加密:
from cryptography.fernet import Fernet
class SecureEmployeeManager(EmployeeManager):
def __init__(self, encryption_key):
super().__init__()
self.cipher = Fernet(encryption_key)
def save_to_file(self, filename):
data = super().save_to_file(filename)
encrypted = self.cipher.encrypt(data)
# 写入加密数据
八、项目展望
扩展方向 | 技术方案 | 商业价值 |
---|---|---|
分布式架构 | 使用gRPC实现多节点通信 | 支持大型企业部署 |
数据分析 | 集成Pandas生成统计报表 | 提供人力资源管理决策支持 |
生物认证 | 集成人脸识别API | 增强安全认证 |
云同步 | 对接AWS S3/阿里云OSS | 实现多地数据同步 |
智能搜索 | 实现Elasticsearch集成 | 支持复杂查询 |
通过持续迭代,可发展为面向不同行业场景的智能人事管理解决方案。
运行以上项目,要求Python版本 3.9 级以上