1. 程式人生 > >python實現小型教務管理系統,操作xml

python實現小型教務管理系統,操作xml

前景

學習python中看到廖老師的xml操作,便想著來玩一把~大概有sax等幾種方法,由於感覺這種比較麻煩,便找到了xml.etree.Element這個模組,輕量級的操作xml,挺好用的,關於記憶體佔用的問題,因為還沒遇到,似乎文件裡面有解決方案。學了xml操作之後,便學著用到小專案裡面,順便簡單的學習了一下MVC這種架構。

思路

  • view層,只負責資料的顯示,和向model層去請求資料。
  • controller 層,負責接受使用者的指令,呼叫檢視,讓檢視去向model請求資料,拿到資料之後,通過view層顯示資料。更改資料時,接受使用者指令,直接作用於model之上
  • model層,獨立於控制器,和檢視,可以獨自進行資料的查,改

模組說明

這裡寫圖片描述

  • view.py 負責向model請求資料,然後顯示資料
  • control.py 負責接受使用者的指令,所有使用者指令全部由它來接受,然後由它去呼叫view顯示資料,呼叫model修改資料。只負責控制整個過程。
  • model.py model層能獨立於其它兩層,它所有的實質功能都由它來操作,view只能呼叫它的功能
  • Operator.py 負責操作資料xml的檔案,也屬於model層,為了清楚點,單獨用了一個模組,model,py呼叫它來執行資料修改.然後修改之後,美化xml。

程式碼示例

  • view.py
from model.student模型 import
Student as S # 驗證ID的存在性 def vertify(ID): if S.vertify(ID) == '存在': return '存在' else: return '不存在' def get_all(ID): a = S(ID) return a.get_all() def get_item(ID,attribute): a = S(ID) if attribute == 'time': return a.time if attribute == 'name'
: return a.name if attribute == 'sex': return a.sex if attribute == 'grade': return a.grade if __name__ == '__main__': print(vertify('001')) print(get_all('002')) print(get_item('002', 'time'))
  • control
# 控制器,不同層面之間的組織作用,用於控制應用程式的流程,接收使用者的行為,操作模型和檢視
from model.student模型 import Student as S
from view import view
if __name__ == '__main__':
    print('**歡迎光臨學生教務管理系統**')
    choice = input('功能選項:\n1:檢視學生的資訊\n2:刪除學生的資訊\n3:新增學生資訊\n4:修改學生的資訊:\n')
    # 這部分來驗證學生的存在性
    if choice == '1' or choice == '2' or choice == '4':
        while True:
            ID = input('輸入你要操作的學生學號\n')
            # 通知檢視view去model裡面查詢有沒有這個學生的資訊
            result = view.vertify(ID)
            if result != '不存在':
                break
            else:
                print('你要找的學生不存在,請重新輸入')
    if choice == '1':
        print(view.get_all(ID))
    if choice == '2':
        S.deltete(ID)
        print('刪除成功')
    if choice == '3':
        print('按提示輸入學生的資訊')
        while True:
            ID = input('輸入學生的學號')
            if view.vertify(ID) == '不存在':
                time = input('輸入學生的入學時間')
                name = input('輸入學生的名字')
                sex = input('輸入學生的性別')
                grade = input('輸入學生的成績')
                S.add(ID, time, name, sex, grade)
                print('新增成功')
                break
            else:
                print('該學號已經存在,請重新輸入')
    if choice == '4': 
        temp = input('1:修改學生的入學時間\n2:修改學生的名字\n3:修改學生的性別\n4:修改學生的成績\n')
        dicta = {'1': 'time', '2': 'name', '3': 'sex', '4': 'grade'}
        info = view.get_item(ID, dicta[temp])
        content = input('學生當前的資訊為:{0},輸入修改之後的值\n'.format(info))
        a = S(ID)
        if temp == '1':
            a.time = content
        if temp == '2':
            a.name = content
        if temp == '3':
            a.sex = content
        if temp == '4':
            a.grade = content
        print('修改成功')
  • student模型.py
# model層主要封裝業務的資料及資料處理的方法
from model.Operator import Operator as op


class Student:

    def __init__(self, value):
        self.__id = value
        lista = op.get(value)
        self.__time, self.__name, self.__sex, self.__grade = lista

    @staticmethod
    def vertify(ID):
        if op.verify(ID):
            return '存在'

    def get_all(self):
        return '學號{0}的資訊為:{5}入學時間:{1}{5}姓名:{2}{5}性別:{3}{5}成績:{4}{5}'.format(self.__id, self.__time, self.__name, self.__sex, self.__grade, '\n')

    @staticmethod
    def deltete(ID):
        op.delete(ID)

    @staticmethod
    def add(ID,time,name,sex,grade):
        op.increase(ID, time, name, sex, grade)

    @property
    def id(self):
        return self.__id

    @property
    def time(self):
        return self.__time

    @time.setter
    def time(self, value):
        op.modify(self.__id, 'time', value)
        self.__time = value

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        op.modify(self.__id, 'name', value)
        self.__name = value

    @property
    def sex(self):
        return self.__sex

    @sex.setter
    def sex(self, value):
        op.modify(self.__id, 'sex', value)
        self.__sex = value

    @property
    def grade(self):
        return self.__grade

    @grade.setter
    def grade(self, value):
        op.modify(self.__id, 'sex', value)
        self.__grade = value


if __name__ == '__main__':
    a = Student('002')
    print(a.get_all())
  • OPerator.py
# 用來處理資料的層
import xml.etree.ElementTree as ET
def indent(elem, level=0):
    i = "\n" + level * "\t"
    # 如果有子節點
    if len(elem):
        # 如果element裡面text為空,或者只有空格
        if elem.text is None or elem.text.isspace():
            elem.text = i + "\t"
        # 如果element尾部沒有內容
        if elem.tail is None or elem.tail.isspace():
            elem.tail = i
        # 如果是最外層的,尾部就不必有格式了
        if level == 0:
            elem.tail = ""
        # 對裡面的每一個節點都執行這樣的縮排
        for elem in elem:
            indent(elem, level + 1)
        # 執行完了之後,此時的elem是當前父節點的最後一個子節點,由於每個子節點之後都會是/n+/t的縮排,所以最後一個節點的tail = /n+/t
        # 注意,呼叫完了indent(elem,level + 1)之後,會回到這一行,此時level為0,element為最後一個子節點,i為/n
        # print(elem,repr(i))  # <Element 'test2' at 0x7fda7b2c0a48> '\n'
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        # 如果沒有子節點
    else:
        if level and (elem.tail is None or elem.tail.isspace()):
            elem.tail = i
            elem.text = elem.text.strip()

class Operator:
    @staticmethod
    def verify(ID):
        tree = ET.parse('../data.xml')
        root = tree.getroot()
        for student in root.iter('student'):
            if student.get('id') == ID:
                return True
            else:
                pass

    @staticmethod
    def get(ID):
        temp = []
        tree = ET.parse('../data.xml')
        root = tree.getroot()
        for student in root.iter('student'):
            if student.get('id') == ID:
                for item in student:
                    temp.append(item.text)
        return temp

    @staticmethod
    def delete(ID):
        tree = ET.parse('../data.xml')
        root = tree.getroot()
        for student in root.findall('student'):
            if student.get('id') == ID:
                root.remove(student)
        indent(root)
        tree.write('../data.xml', encoding='utf-8')

    @staticmethod
    def increase(ID, time, name, sex, grade):
        tree = ET.parse('../data.xml')
        root = tree.getroot()
        student_id = ET.Element('student')
        student_id.set('id', ID)
        stu_time = ET.Element('time')
        stu_time.text = time
        stu_name = ET.Element('name')
        stu_name.text = name
        stu_sex = ET.Element('sex')
        stu_sex.text = sex
        stu_grade = ET.Element('grade')
        stu_grade.text = grade
        root.append(student_id)
        student_id.extend((stu_time, stu_name, stu_sex, stu_grade))
        indent(root)
        tree.write('../data.xml', encoding='UTF-8')

    @staticmethod
    def modify(ID, item, comment):
        tree = ET.parse('../data.xml')
        root = tree.getroot()
        for student in root.findall('student'):
            if student.get('id') == ID:
                temp = student.find(item)
                temp.text = comment
        indent(root)
        tree.write('../data.xml', encoding='UTF-8')

if __name__ == '__main__':
    a = Operator()
    results = a.get('001')
    print(results)
    a.modify('002', 'time', '2016')
    a.modify('002', 'grade', '99')
    print(a.verify('002'))
    print(a.get('002'))
    a.increase('003', '2016', '張三', '女', '98')
    a.delete('003')
  • data.xml
<exam>
    <student id="001">
        <time>2015</time>
        <name>張三</name>
        <sex></sex>
        <grade>90</grade>
    </student>
    <student id="002">
        <time>2016</time>
        <name>李四</name>
        <sex></sex>
        <grade>99</grade>
    </student>
</exam>

效果展示

  • 檢視學生資訊
    這裡寫圖片描述

  • 新增學生資訊
    這裡寫圖片描述
    這裡寫圖片描述

  • 刪除學生資訊
    這裡寫圖片描述
    這裡寫圖片描述

  • 修改學生資訊
    這裡寫圖片描述
    這裡寫圖片描述

總結

  • 優點
    • 用到了MVC分層的思想
    • 運用了xml.etree.element模組
    • 美化了修改的XML
    • 簡單的封裝了所用的程式碼
  • 不足之處
    • 由於是第一次實際用到類,對類的書寫還比較混亂,並不知道怎樣正確地寫一個類,需要改進,但是自己不知道怎麼去改
    • 要是用個GUI來實現功能會比較好,使用者體驗更好

雖說,程式碼寫的蠻爛哈哈哈~不過總歸是自己的一個練手小專案,玩的太少。還是第一次用分層的思想去實現自己的小專案,自己動手寫了這麼些程式碼,小有成就感~有待up~加油啦~,希望看到的各位大神,能指出我的不足,讓我能夠修改。完善,3Q

參考連結

  • 資料量大的時候記憶體溢位
  • 內建的這個模組,生成xml檔案標籤的屬性時,屬性順序會按照字典順序重排