1. 程式人生 > >python實現一個大學的人員管理系統

python實現一個大學的人員管理系統

python作為一個面對物件的程式設計語言,實現一個人員管理系統有自己關於類的方法。

首先,通過定義一個人員的類物件,實現對於人員公共特性的支援,公共的特性包括:姓名,性別,出生日期等,用一個Person類來表示。大學裡總的來說分為兩種身份的人:學生(Student)和職工(Staff),這兩種有自己的特性,比如學生資訊就有學號,課程,成績等;職工有職工號,職位,薪水等。
利用python類物件的繼承機制我們就可以很方便的表示這兩種身份的人。
我們首先定義一個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")

以上實現了一個通用的人資訊的類,接下來有學生和職工的類都是繼承自這個基類。

接下來我們看學生類的實現:
提前講一下,學生類有一個學號的自動生成函式,在類內自動呼叫生成學號

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函式,進行基類方法的呼叫

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很有幫助。