修改类变量为何属于不良实践?员工信息存储类如何优雅实现
问题解答
1. 修改类变量是否属于不良编程实践?
不是所有修改类变量的操作都属于不良实践,只有不符合类变量设计定位、违反设计原则的修改操作才是不推荐的,你当前的用法属于需要优化的情况,具体原因如下:
- 违反单一职责原则:Employee类同时承担了「定义单个员工属性与行为」和「全局维护全公司员工档案」两个完全独立的职责,后续任何一端的需求变更都会影响另一端的代码。
- 全局状态不可控:类变量是全局共享的,项目任意位置都可以直接修改
Employee.company_records、Employee.Employee_count的值,很容易出现数据不一致的问题。比如你示例代码中第二次给emp_2赋值时,旧的emp_2实例已经没有引用,但对应的记录还留在全局字典中,会产生无用的垃圾数据。 - 扩展性差:如果后续需要按部门、分子公司分别存储员工记录,当前类变量的写法完全无法支持,不可能为每个部门单独创建一个Employee子类。
- 测试难度高:单元测试时无法隔离员工记录数据,不同测试用例会修改同一个全局类变量,互相干扰导致测试结果不准确。
2. 需求的优雅实现方案
核心优化思路是拆分职责,将「单个员工实体」和「员工档案管理容器」拆分为两个独立的类,避免逻辑耦合。以下是参考实现:
from dataclasses import dataclass from typing import Dict, Optional # 单个员工实体类:仅维护单个员工的属性与相关行为 @dataclass class Employee: fname: str lname: str email_id: str contact: int gender: str # 用property装饰器,把fullname变成可直接访问的属性,不用加括号调用 @property def fullname(self) -> str: return f"{self.fname} {self.lname}" # 公司员工档案管理类:仅负责所有员工记录的增删改查操作 class CompanyRecords: def __init__(self): # 员工记录和计数变成实例变量,每个档案容器实例互相独立 self.records: Dict[int, Employee] = {} self.employee_count: int = 0 def add_employee(self, employee: Employee) -> int: self.employee_count += 1 self.records[self.employee_count] = employee return self.employee_count # 可按需扩展其他操作方法 def get_employee_by_id(self, emp_id: int) -> Optional[Employee]: return self.records.get(emp_id) def delete_employee(self, emp_id: int) -> bool: if emp_id in self.records: del self.records[emp_id] return True return False # 使用示例 if __name__ == "__main__": # 初始化bcoder公司的档案容器,如需存储其他公司/部门的档案,再实例化新的对象即可 bcoder_company_records = CompanyRecords() emp_1 = Employee("Vaibhav", "Yadav", "vaibhavy1912@gmail.com", 9432098712, "Male") bcoder_company_records.add_employee(emp_1) print(emp_1.fullname) # 输出和原有代码格式一致的记录 print({eid: { "Name": emp.fullname, "Email_id": emp.email_id, "Contact": emp.contact, "Gender": emp.gender } for eid, emp in bcoder_company_records.records.items()}) emp_2 = Employee("vaibhav", "Gupta", "hg1123@gmail.com", 9323118976, "male") bcoder_company_records.add_employee(emp_2) print({eid: { "Name": emp.fullname, "Email_id": emp.email_id, "Contact": emp.contact, "Gender": emp.gender } for eid, emp in bcoder_company_records.records.items()}) emp_3 = Employee("Yogesh", "Yadav", "yogesh1123@gmail.com", 9323118976, "male") bcoder_company_records.add_employee(emp_3) print({eid: { "Name": emp.fullname, "Email_id": emp.email_id, "Contact": emp.contact, "Gender": emp.gender } for eid, emp in bcoder_company_records.records.items()})
该方案的优势如下:
- 职责清晰,两个类的逻辑完全分离,后续修改互不影响
- 数据操作可控,所有档案的修改都需要通过
CompanyRecords提供的方法执行,避免意外篡改数据 - 扩展性强,支持同时维护多个独立的员工档案集合,适配分部门、分公司的管理需求
- 测试友好,每个测试用例可单独实例化
CompanyRecords对象,测试数据完全隔离,不会互相干扰
内容的提问来源于stack exchange,提问作者Vaibhav Yadav
相关产品推荐
相关产品推荐

