Python面向对象实现大学人员管理系统详解
本文基于Python面向对象特性,详细讲解如何构建大学人员管理系统。通过定义Person基类及Student、Staff子类,利用继承机制实现学生与职工信息的统一管理。文中包含完整的代码示例,涵盖学号自动生成、成绩管理及薪资处理等核心功能,适合Python初学者深入理解类与对象的应用。
系统概述与类设计思路
Python作为一种面向对象的程序设计语言,在实现人员管理系统时,其核心优势在于对类与对象机制的支持。
首先,我们需要定义一个代表人员公共特性的基类。该公共特性包括姓名、性别和出生日期等,通过一个Person类来表示。在大学环境中,人员主要分为两类身份:学生(Student)和职工(Staff)。这两类身份拥有各自特有的属性,例如学生包含学号、修读课程和成绩等信息;而职工则包含职工号、职位和薪水等数据。
利用Python类对象的继承机制,我们可以非常便捷地表示这两种不同身份的人员结构。
我们首先定义Person类,该类用于保存所有人员共有的基础特性。
基类Person实现与公共属性管理
import datetime
class PersonValueError(ValueError):
pass
class PersonTypeError(TypeError):
pass
class Person:
_num = 0
# 类属性,这个属性在类内使用(_X)属性一般默认只能在类内使用
def __init__(self, name, sex, birthday, ident):
if not (isinstance(name, str) and sex in ("女", "男")):
raise PersonValueError(name, sex)
# 用于检查输入时的实参是否符合要求
try:
birthday = datetime.date(*birthday)
# *birthday表示其参数是一个可迭代的对象(元祖,列表等)
# 返回一个日期对象(year,month,day),这个date类的
# 构造函数会检查输入年月日的合法性
except:
raise PersonValueError("wrong date:", birthday)
self._name = name
self._sex = sex
self._birthday = birthday
self._id = ident
Person._num += 1
def id(self):return self._id
def name(self):return self._name
def sex(self):return self._sex
def birthday(self):return self._birthday
def age(self): return (datetime.date.today().year - self._birthday.year)
# 用于获取一个单体的某个信息
# 算出年龄(today方法的year属性用于给出今年)
def set_name(self, name): # 修改名字
if not isinstance(name, str):
raise PersonValueError("set_name", name)
self._name = name
# 用于修改名字
def __lt__(self, another):
# 当实例出现在小于号两边时会自动调用
# 类似的有:__gt__: 大于; __le__:小于等于; __ge__: 大于等于;
# __eq__: 等于; __ne__: 不等于
if not isinstance(another, Person):
raise PersonTypeError(another)
return self._id < self._id
# 用于之后的排序使用
@classmethod
def num(cls):
return Person._num
def __str__(self):
return " ".join((str(self._id), self._name, self._sex, str(self._birthday)))
# 运算重载符:当实例出现在print函数中时,自动调用这个方法
def details(self):
return ", ".join(("编号:" + str(self._id),
"姓名:" + self._name,
"性别:" + self._sex,
"出生日期:" + str(self._birthday)))
#
# p1 = Person("谢雨洁", "女", (1995, 7, 30), 1201510111)
# p2 = Person("汪力强", "男", (1990, 2, 17), 1201380324)
# p3 = Person("张子玉", "女", (1974, 10, 14), 3331747032)
# p4 = Person("李国栋", "男", (1962, 5, 24), 1293848593)
#
# plist = [p1, p2, p3, p4]
# for p in plist:
# print(p)
# # 这里就会直接调用实例方法__str__
#
# print("\nAfter sorting:")
# plist.sort()
# # 这里就调用的运算重载符__lt__(很重要的一个知识点,如何通过实例方法实现对类多个实例进行排序)
# for p in plist:
# print(p.details())
#
# print("people created:", Person.num(), "\n")
上述实现了一个通用的个人信息类,后续的学生类和职工类均继承自这个基类。
接下来我们查看学生类的具体实现细节。
需要特别说明的是,学生类包含一个学号自动生成函数,该函数在类内部被自动调用以生成唯一的学号。
学生类Student实现与学号自动生成
class Student(Person):
_id_num = 0
# 下面这个类方法可以说是很经典的使用,对于初学者来说,对于深入理解类有帮助
@classmethod
**def _id_gen(cls):
# 自动生成学号的类内部函数(该函数只在类的内部调用)
cls._id_num += 1
year = datetime.date.today().year
return "1{:04}{:05}".format(year, cls._id_num)
# 后面的04, 05代表是位数,不足前面补零**
def __init__(self, name, sex, birthday, department):
Person.__init__(self, name, sex, birthday, Student._id_gen())
# 这里通过调用之前基类的初始化函数
# 这里调用了之前定义的生成学号的类方法
self._department = department
self._enroll_date = datetime.date.today()
self._courses = {} #实例属性用来记录该学生的课程以及成绩
def set_course(self, course_name):
self._courses[course_name] = None
# 输入所有的课程
def set_score(self, course_name, score):
if course_name not in self._courses:
raise PersonValueError("No this course selected:",
course_name)
self._courses[course_name] = score
# 当然我们对于学生的档案里首先时学生要挑选好课程,然后才有分数
# 首先判断课程在不在已选的课程表里,然后再是给他输入分数
def scores(self):
return [(cname, self._courses[cname])
for cname in self._courses]
# 将课程和分数用元祖的形式输出
def details(self):
return ", ".join((Person.details(self),
"入学日期:" + str(self._enroll_date),
"院系:" + self._department,
"课程记录:" + str(self.scores())))
# p1 = Student("谢雨洁", "女", (1995, 7, 30), "Physics")
# p2 = Student("汪力强", "男", (1990, 2, 17), "Mathematics")
# p3 = Student("张子玉", "女", (1974, 10, 14), "English")
# p4 = Student("李国栋", "男", (1962, 5, 24), "Comp.Sci")
#
# print(p1.details())
# print(p1) # 继承的基类Person的方法
最后是职工类的实现。与之前的学生类不同,职工类不能直接调用基类的初始化函数,这里建议使用super函数来正确调用基类的方法。
职工类Staff实现与super方法调用
class Staff(Person):
_id_num = 0
@classmethod
def _id_gen(cls, birthday):
cls._id_num += 1
birth_year = datetime.date(*birthday).year
return "0{:04}{:05}".format(birth_year, cls._id_num)
def __init__(self, name, sex, birthday, entry_date=None):
super().__init__(name, sex, birthday,Staff._id_gen(birthday))
if entry_date:
try:
self._entry_date = datetime.date(*entry_date)
except:
raise PersonValueError("Wrong date:", entry_date)
else:
self._entry_date = datetime.date.today()
self._salary = 1720
self._department = "未定"
self._position = "未定"
def set_salary(self, amount):
if not type(amount) is int:
raise TypeError
self._salary = amount
def set_position(self, position):
self._position = position
def set_department(self, department):
self._department = department
def details(self):
return ", ".join((super().details(),
"入职时间:" + str(self._entry_date),
"院系:" + self._department,
"职位:" + self._position,
"工资:" + str(self._salary)))
p1 = Staff("张子玉", "女", (1974, 10, 16))
p2 = Staff("李国栋", "男", (1962, 5, 24))
print(p1)
print(p2)
p1.set_department("数学")
p1.set_position("副教授")
p1.set_salary(8400)
print(p1.details())
print(p2.details())
代码参考《数据结构与算法 python语言描述》。强推这本书,对于深入理解Python很有帮助。
更多学习资料请关注专题《管理系统开发》。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









