1. 程式人生 > >python面向對象編程習題一

python面向對象編程習題一

修改用戶 obj 模塊 反序 init 獲取 tin 是否 操作

1.編寫程序, 編寫一個學生類, 要求有一個計數器的屬性, 統計總共實例化了多少個學生

技術分享圖片
class Student:
    """學生類"""
    count = 0  # 計數
    def __init__(self, name, age):
        self.name = name
        self.age = age
        Student.count += 1  # 要使得變量全局有效,就定義為類的屬性

    def learn(self):
        print("is learning")


stu1 = Student("jack"
, 33) stu2 = Student("amy", 24) stu3 = Student("lucy", 22) stu4 = Student("lulu", 45) print("實例化了%s個學生" % Student.count) 輸出: 實例化了4個學生
View Code

2.編寫程序, A 繼承了 B, 倆個類都實現了 handle 方法, 在 A 中的 handle 方法中調用 B 的 handle 方法

技術分享圖片
class B:
    """類B"""
    def __init__(self):
        pass

    def handle(self):
        
print("B.handle") class A(B): """類A""" def __init__(self): super().__init__() def handle(self): super().handle() # super依賴於繼承 a = A() a.handle() 輸出: B.handle
View Code

3.編寫程序, 如下有三點要求:

  1. 自定義用戶信息數據結構, 寫入文件, 然後讀取出內容, 利用json模塊進行數據的序列化和反序列化
  2. 定義用戶類,定義方法db,例如 執行obj.db可以拿到用戶數據結構
  3. 在該類中實現登錄、退出方法, 登錄成功將狀態(status)修改為True, 退出將狀態修改為False(退出要判斷是否處於登錄狀態).密碼輸入錯誤三次將設置鎖定時間(下次登錄如果和當前時間比較大於30秒即不允許登錄)

用戶數據結構:user_info

{
    "egon":{"password":"123",status:False,timeout:0},
    "alex":{"password":"456",status:False,timeout:0},
}
技術分享圖片
import json
import time
# data = {
#     "egon":{"password":"123",‘status‘:False,‘timeout‘:0},
#     "alex":{"password":"456",‘status‘:False,‘timeout‘:0},
# }
#
# with open("user_info", "w", encoding="utf-8") as f:
#     json.dump(data, f)  # 序列化


class User:
    """用戶類"""
    def __init__(self):
        self.user_dic = self.read()  # 初始化時將用戶信息讀取出來
        self.username = ""  # 記錄當前登錄用戶

    def write(self):
        """序列化"""
        with open("user_info", "w", encoding="utf-8") as f:
            json.dump(self.user_dic, f)  # 序列化

    def read(self):
        """拿到用戶數據"""
        with open("user_info", "r", encoding="utf-8") as f:
            user_dic = json.load(f)  # 反序列化
            return user_dic

    def db(self):
        print("用戶數據結構:", self.user_dic)

    def login(self):
        """登錄"""
        i = 0
        while i < 3:
            username = input("username:").strip()
            password = input("password:").strip()
            if username in self.user_dic and password == self.user_dic[username]["password"]:
                time_now = time.time()  # 獲取當前時間
                period = time_now - self.user_dic[username]["timeout"]  # 時間差
                if period >= 30:  # 判斷時間間隔是否滿足登錄條件
                    print("------%s登陸成功-----" % username)
                    self.username = username
                    self.user_dic[username]["status"] = True  # 記錄用戶登錄狀態
                    self.write()  # 將修改保存到文件
                    break
                else:
                    print("用戶處於鎖定狀態,請%s S後再試" % (30 - period))
                    break
            else:
                print("用戶名或密碼錯誤!")
                i += 1
                if i == 3 and username in self.user_dic:
                    self.user_dic[username]["timeout"] = time.time()  # 記錄3次登錄失敗的時間點
                    self.write()  # 將修改保存到文件
                    exit("退出")

    def exit(self):
        """退出"""
        if self.username:  # 用戶處於登錄狀態
            self.user_dic[self.username]["status"] = False  # 修改用戶登錄狀態
            self.write()  # 將修改保存到文件
            exit("用戶%s退出登錄" % self.username)

    def help_info(self):
        """幫助信息"""
        print("""命令列表:
         查看數據結構:db
         登錄:login
         退出登錄:exit""")

    def handle(self):
        """處理用戶輸入命令"""
        while True:
            cmd = input("請輸入命令:").strip()
            cmd = cmd.split()
            if hasattr(self, cmd[0]):  # 使用反射
                func = getattr(self, cmd[0])  # 拿到方法名
                func()
            else:
                self.help_info()  # 打印幫助信息


user = User()
if __name__ == "__main__":
    user.handle()

"""
輸出:
請輸入命令:login
username:egon
password:123
------egon登陸成功-----
請輸入命令:exit
用戶egon退出登錄
"""
View Code

4.用面向對象的形式編寫一個老師角色, 並實現以下功能, 獲取老師列表, 創建老師、刪除老師、創建成功之後通過 pickle 序列化保存到文件裏,並在下一次重啟程序時能
讀取到創建的老師, 例如程序目錄結構如下.

proj
|-- bin/
|   |-- start.py         程序啟動文件
|-- config/
|   |-- settings.py     程序配置(例如: 配置存儲創建老師的路徑相關等)
|-- db                  數據存儲(持久化, 使得每次再重啟程序時, 相關數據對應保留)
|   |-- teachers/          存儲所有老師的文件
|   |-- ...                ...
|-- src/                程序主體模塊存放
|   |-- __init__.py
|   |-- teacher.py      例如: 實現老師相關功能的文件
|   |-- group.py        例如: 實現班級相關的功能的文件
    |-- main.py         程序運行主體程序(可進行菜單選擇等)
|-- README.md 程序說明文件

技術分享圖片

代碼:

技術分享圖片
# start.py
"""程序啟動文件"""
import os
import sys
BASE_PATH = os.path.dirname(os.getcwd())
sys.path.insert(0, BASE_PATH)  # 將proj的路徑添加到模塊搜索路徑中
from src import main

if __name__ == "__main__":
    main.main()


# settings.py
"""定義一些常量"""
import os

BASE_PATH = os.path.dirname(os.getcwd())
teacher_file = os.path.join(BASE_PATH, "db", "teacher_info")  # 教師文件路徑


# main.py
"""程序運行主體,可進行菜單選擇"""
from src.manager import Manager


def main():
    li = Manager.info
    for i in range(len(li)):
        print(i+1, li[i][0])
    while True:
        ch = input("輸入序號進行操作:").strip()
        getattr(Manager(), li[int(ch)-1][1])()  # 反射, 找到對象相應的方法並執行


# manager.py
"""創建教師,刪除教師,查看教師"""
from src.my_pickle import MyPickle
from config.settings import *
from src.teacher import Teacher


class Manager:
    """管理員類"""
    info = [("查看教師", "show_teacher"),("創建教師", "create_teacher"),
            ("刪除教師", "delete_teacher"), ("退出", "exit")]

    def __init__(self):
        self.teacher_pickle_obj = MyPickle(teacher_file)  # 實例化MyPickle類,teacher_file是settings中的教師文件路徑

    def show(self, pickle_obj):
        """從文件中讀取信息"""
        pick_obj = getattr(self, pickle_obj)
        data_g = pick_obj.readiter()  # 讀取對象信息
        for teacher_obj in data_g:
            for key in teacher_obj.__dict__:
                print(key, teacher_obj.__dict__[key])  # 打印對象信息
            print("-" * 50)

    def show_teacher(self):
        """查看教師信息"""
        print("教師信息".center(45, "-"))
        self.show("teacher_pickle_obj")

    def create_teacher(self):
        """創建教師信息"""
        name = input("輸入要創建的教師姓名:").strip()
        school = input("輸入教師所在學校:").strip()
        teacher = Teacher(name, school)  # 實例化一個教師對象
        self.teacher_pickle_obj.write(teacher)  # 將對象寫入文件
        print("創建教師成功!")

    def delete_teacher(self):
        """刪除教師信息"""
        self.show_teacher()
        inp = input("輸入要刪除的教師姓名:").strip()
        self.teacher_pickle_obj.delete(inp)  # 刪除
        print("刪除成功!")

    def exit(self):
        exit()


# my_pickle.py
"""讀寫文件信息"""
import pickle
import os
from config.settings import *


class MyPickle:
    def __init__(self, filename):
        self.filename = filename

    def write(self, data):  # 寫入
        with open(self.filename, "ab") as f:
            pickle.dump(data, f)

    def readiter(self):  # 讀取
        with open(self.filename, "rb") as f:
            while True:
                try:
                    data = pickle.load(f)
                    yield data
                except:
                    break

    def delete(self, name):  # 刪除
        f2 = MyPickle(self.filename+".bak")  # 新建一個文件
        for item in self.readiter():  # 從文件中load數據
            if item.name == name:
                pass  # 找到了就不寫入
            else:
                f2.write(item)  # 沒找到就將對象寫入文件
        os.remove(self.filename)  # 刪除舊文件
        os.rename(self.filename+".bak", self.filename)  # 新文件名重命名為舊文件名


# teacher.py

class Teacher:
    """教師類"""
    def __init__(self, name, school):
        self.name = name
        self.school = school
View Code

python面向對象編程習題一