學Python這麼久了,第一次寫一個這麼多的代碼(我承認只有300多行,重覆的代碼挺多的,我承認我確實垃圾),但是也挺不容易的 自定義函數+裝飾器,每一個模塊寫的一個函數 很多地方能用裝飾器(邏輯跟不上,有的地方沒用),包括雙層裝飾器(不會),很多地方需要優化,重覆代碼太多 我還是把我的流程圖拿出來 ...
學Python這麼久了,第一次寫一個這麼多的代碼(我承認只有300多行,重覆的代碼挺多的,我承認我確實垃圾),但是也挺不容易的
自定義函數+裝飾器,每一個模塊寫的一個函數
很多地方能用裝飾器(邏輯跟不上,有的地方沒用),包括雙層裝飾器(不會),很多地方需要優化,重覆代碼太多
我還是把我的流程圖拿出來吧,雖然看著比上次的垃圾,但是我也做了一個小時,不容易!
好像是挺醜的(表示不會畫,但我下次一定努力)
用戶文件:
文件名為:user.txt
1代表管理員用戶
2代表普通用戶
smelond|admin|[email protected]|1 admin|admin|[email protected]|2 qwe|qweasd|[email protected]|2
代碼(感覺這個程式還有很多bug):
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # File_type:用戶管理程式,裝飾器版本,多功能 # Filename:user_manage_program.py # Author:smelond import os os.system("cls") # windows中的清屏 COUNT = 0 # 計數器 WHETHER_LOGIN = {"is_login": "error"} # 用於判斷是否有用戶登錄 USER_LIST = [] # 當前用戶信息存放的列表 def register_function(): # 註冊函數 (所有註冊都來調用這個函數) count = 3 # 計數器,做到了一個提示用戶的作用 for i in range(3): # 迴圈3次 print("用戶註冊【你只有3次機會】,你還有【%s】次機會".center(80, "=") % count) # 輸出提示 count -= 1 # 每次減1 username = input("請輸入用戶名:") while True: passwd = input("請輸入密碼:") if len(passwd) >= 5: break else: # 如果輸入的密碼小於5,位數,向下操作 print("請輸入大於5位數的密碼") input_passwd = input("【1:繼續輸入;2:返回上一步】") if input_passwd == "1": pass else: main() while True: email = input("請輸入郵箱:") email_count = email.count("@") # 查看輸入的郵箱是否帶@, # print(email_count) # 返回1代表有一個@ if email_count == 1: break # 如果有一個@符號,代表郵箱輸入正確,跳出當前迴圈 else: print("請輸入正確的郵箱") input_email = input("【1:繼續輸入;2:返回上一步】") if input_email == "1": pass else: main() register_user = [username, passwd, email, "2"] # 將我們輸入的用戶名密碼以及郵箱放到一個列表中,普通用戶,所以加上了一個2 with open("user.txt", "r") as user: for line in user: f_user_list = line.strip("\n").split("|") if register_user[0] == f_user_list[0]: print("用戶名已被註冊") break if register_user[2] == f_user_list[2]: # 判斷我們輸入得的郵箱和用戶名是否以及存在 print("郵箱已被註冊") break else: # 接下來是通過了上面的篩選,開始把我們的註冊信息寫進資料庫(總感覺上面有bug) user_write = "|".join(register_user) # 用join方法將這個列表轉換為以|分隔 # open_user = open("user.txt", "a") # a 以追加方式寫入文件 # open_user.write("\n" + user_write) # open_user.close() # 記得關閉 with open("user.txt", "a") as f: f.write("\n" + user_write) # 跟上面一樣的方法,這種不用關閉文件 print("註冊成功") user_write = """用戶名:【%s】;密碼:【%s】;郵箱:【%s】""" \ % (register_user[0], register_user[1], register_user[2]) # 註冊成功的提示信息 return user_write # 返回提示信息 def outer(func): # 裝飾器,用於管理介面 def inner(*args, **kwargs): if WHETHER_LOGIN["is_login"] == "success" and USER_LIST[3] == "1": # 為什麼要加上引號,因為在列表中存儲的是字元串,而不是整形 r = func() # 執行我們傳入的函數 return r # 返回 elif WHETHER_LOGIN["is_login"] == "success" and USER_LIST[3] == "2": # 如果為普通用戶,提示沒有足夠許可權並且返回到main函數 print("\n當前用戶為普通用戶【%s】,沒有足夠的許可權" % USER_LIST[0]) main() else: print("\n當前沒有用戶登錄,請登錄後再試。。。") # 否者就是沒有登錄了 main() return inner def user_login(func): # 檢測用戶是否登錄的裝飾器 def inner(*args, **kwargs): if WHETHER_LOGIN["is_login"] == "success": # 判斷是否登錄 r = func() return r # 如果已經登錄,返回到原本的函數 else: user_no = input("請登錄後再試【1:用戶登錄;2:返回】:") if user_no == "1": login() else: print("返回成功") main() return inner # 切記,這裡必須返回一個inner,不然上面的inner不會執行,不能再後面加(),如果加上了,就相當於調用這個函數 def exit_login(): # 6退出登錄 global USER_LIST if USER_LIST: quit_login = input("當前用戶為【%s】,確定要退出【Y/N】:" % USER_LIST[0]) # if quit_login == "Y" or quit_login == "y" or quit_login == "yes": if quit_login in ("Y", "y", "yes", "yES", "yeS", "yEs", "YES", "Yes", "YEs"): # 如果quit_login滿足其中一個,繼續執行 WHETHER_LOGIN["is_login"] = "error" USER_LIST = [] # 直接將列表清除為初始狀態,不知道這種方法好不好,但是好像管用 elif quit_login in ("N", "n", "No", "nO", "NO"): print("退出失敗") else: print("沒有用戶登錄。。。") def verifi_passwd(): with open("user.txt", "r") as old_user: lines = old_user.readlines() # 一次性讀取整個文件,感覺這方方式不好 flag = True cout = 3 while flag: cout -= 1 user_info = input("請輸入用戶名:") if user_info == "": # 判斷是否輸入字元串 print("你沒有輸入任何用戶。。。\n") manage() for line in lines: user_all_info = line.strip("\n").split("|") if user_info == user_all_info[0]: current_user = user_all_info # 如果輸入的用戶和用戶文件裡面的用戶相同,那就將他的所有信息寫入一個新的列表中 flag = False if cout == 0: print("然而,你可能不知道有哪些用戶,趕緊去查看吧。。。") manage() lines_user = [lines, current_user] return lines_user def user_info_func(username, password_or_power, user_info, lines): # 幾個傳入的類型為:用戶名、密碼或用戶許可權,需要修改的用戶列表的位置、需要迴圈的文件內容 new_user_info = username.copy() # 將username複製給new_user_info new_user_info[user_info] = password_or_power # 將新的用戶密碼修改為輸入的新密碼 username = "|".join(username) # 將列表轉換為資料庫可以識別的內容 new_user_info = "|".join(new_user_info) # print(username, new_user_info) with open("user.txt", "w") as new_user: for line in lines: # 將返回的整個文件迴圈列印 if username in line: # 如果返回的用戶信息在返回的文件裡面 line = line.replace(username, new_user_info) # 那就將舊的用戶信息替換為新的用戶信息 new_user.write(line) # 寫入文件 print("修改成功") # 提示信息 @outer # 調用裝飾器 def manage(): # 5用戶管理介面 while True: print("用戶管理介面【歡迎管理員[%s]】".center(69, "=") % USER_LIST[0]) print("1:查看所有用戶;2、添加新用戶;3:刪除用戶;4:修改用戶密碼;5:升級用戶許可權;6:退出用戶管理") user_input = input("請輸入對象序號:") if user_input == "1": # 查看用戶信息 print("\n" + "-" * 80) # 列印80個- with open("user.txt", "r") as user_info: for line in user_info: user_list = line.strip("\n").split("|") # 去掉預設的\n和|將他轉換為列表類型 if user_list[3] == "1": user_rights = "管理員用戶" # 用戶最後一個數如果等於1,代表管理員 else: user_rights = "普通用戶" # 否者為普通用戶 ordinary_user = """用戶名【%s】\t密碼【%s】\t郵箱【%s】\t用戶等級【%s】""" \ % (user_list[0], user_list[1], user_list[2], user_rights) # 中間預設有一個換行符 print(ordinary_user) print("-" * 80 + "\n") elif user_input == "2": while True: ret = register_function() # 調用註冊函數 print(ret) # 輸出返回值 break # 跳出當前這個while迴圈 elif user_input == "3": flag = "error" # 預設是沒有用戶的(做到一個提示作用) del_user = verifi_passwd()[1][0] # 得到函數返回的第二個值 print("\033[1;31m刪除用戶為:\033[0m", del_user) with open("user.txt", "r") as old_user: lines = old_user.readlines() # 一次性讀取整個文件,感覺這方方式不好1 with open("user.txt", "w") as new_user: for line in lines: # 將上面讀取到的文集一行一行的迴圈出來 if line.startswith(del_user): # 檢查資料庫裡面是否有我們輸入的用戶(以輸入的用戶名開頭) flag = "success" continue new_user.write(line) if flag == "success": # 提示成功 print("刪除成功") else: print("沒有這個用戶。。。") # 如果輸入的為空格或一些沒有的用戶,提示沒有這個用戶 continue elif user_input == "4": ret = verifi_passwd() # 得到函數返回值 lines = ret[0] # 獲取到返回的整個文件內容 username = ret[1] # 獲取到返回的需要修改密碼的用戶 new_password = input("請輸入用戶的新密碼:") if len(new_password) < 5: # 判斷輸入的密碼長度是否大於或等於5位數 error_prompt = input("你輸入的密碼長度小於5位數,由於你是管理員,輸入Y繼續:").strip("") # 去掉輸入的空格 if error_prompt not in ("y", "Y"): # 如果輸入的值不為y或Y,就直接退出 print("退出。。。") continue user_info_func(username, new_password, 1, lines) # 傳入實參到函數,1在列表中的位置代表用戶的新密碼 elif user_input == "5": # 下麵這部分和上面的部分基本相似,其實可以寫一個函數用來調用的 ret = verifi_passwd() lines = ret[0] username = ret[1] # 獲取到輸入用戶的所有信息 new_power = input("輸入Y提升用戶許可權:") if new_power not in ("y", "Y"): print("輸入錯誤。。。") break user_info_func(username, "1", 3, lines) # 傳入實參:用戶名、許可權(1代表管理員)、位置、迴圈的文件內容 elif user_input == "6": print("返回上一級!!!") main() else: print("輸入有誤") @user_login # 調用裝飾器 def see(): # 4查詢當前用戶的基本信息 if USER_LIST[3] == "1": # 資料庫裡面定義了1代表管理員用戶,2代表普通用戶 user_level = "管理員用戶" else: user_level = "普通用戶" user_see = """ ---------------------------------------- 用戶名: 【%s】 密 碼: 【%s】 郵 箱: 【%s】 用戶等級:【%s】 ---------------------------------------- """ % (USER_LIST[0], USER_LIST[1], USER_LIST[2], user_level) # 一個簡單的格式化輸出 print(user_see) def error_password(): counter = 3 while True: counter -= 1 if counter == 0: print("你輸入錯誤的次數太多,程式自動返回。。。") main() else: print("兩次輸入的密碼不相同。。。") continue @user_login # 調用裝飾器 def alter(): # 3修改密碼 print("當前用戶為:【%s】" % USER_LIST[0]) while True: old_user_password = input("請輸入當前用戶的舊密碼密碼:") if old_user_password == USER_LIST[1]: flag = True count = 3 while flag: count -= 1 new_user_password = input("請輸入當前用戶的\033[1;31m新密碼\033[0m:") # 給新密碼字體加顏色 new_user_password1 = input("再次輸入當前用戶的\033[1;31m新密碼\033[0m:") if len(new_user_password) >= 5: flag = False elif count == 0: print("多次不合法,程式自動返回。。。") main() else: print("輸入不合法,請輸入大於5位數的密碼") if new_user_password == new_user_password1: # 判斷兩次輸入的密碼是否相等 with open("user.txt", "r") as user_info: # 以讀的方式打開這個文件 old_user_info = "|".join(USER_LIST) # 獲取以前的舊信息 for line in user_info: # 將獲取到的每行迴圈輸出 if USER_LIST[0] in line: # 找到當前登錄的用戶的這個用戶名 USER_LIST[1] = new_user_password1 # 如果找到了,就把新密碼重新加入到我們全局的用戶的信息列表中 new_user_info = "|".join(USER_LIST) # 將用戶信息表中的內容用join方法轉換為用戶資料庫裡面的格式(新用戶信息) # print(new_user_info) # print(old_user_info) break # 跳出當前 with open("user.txt", "r") as old_user: lines = old_user.readlines() # 一次性讀取整個文件,感覺這方方式不好 with open("user.txt", "w") as new_user: for line in lines: # 將上面讀取到的文集一行一行的迴圈出來 if old_user_info in line: # 檢查文件裡面是否有我們用戶的舊信息 line = line.replace(old_user_info, new_user_info) # 如果有就用replace替換 new_user.write(line) # 接著寫入到文件 print("修改成功√") break # 完成後跳出 else: # 兩次不相等 print("兩次輸入的密碼不相同,程式自動返回。。。") main() else: # 當前用戶密碼輸入錯誤 print("當前用戶密碼輸入錯誤,程式自動返回。。。") main() def register(): # 2用戶註冊 if WHETHER_LOGIN["is_login"] == "success": quit_login = input("無法註冊用戶,請退出登錄後重試【1:退出登錄;2:返回上一步】:") if quit_login == "1": exit_login() # 跳轉到退出用戶函數 elif quit_login == "2": print("返回成功") elif WHETHER_LOGIN["is_login"] == "error": ret = register_function() # 調用註冊函數 print(ret) # 將返回值輸出 def login(): # 1用戶登錄 print("用戶登錄".center(82, "=")) username = input("請輸入用戶名:") passwd = input("請輸入密碼:") with open("user.txt", "r") as user: for line in user: f_user_list = line.strip("\n").split("|") # 去除每行預設的回車,以及|,並且將它轉換為列表賦給f_admin_list if f_user_list[0] == username and f_user_list[1] == passwd: print("登錄成功") global USER_LIST USER_LIST = f_user_list # 將獲取到的當前行放到用戶信息列表中 WHETHER_LOGIN["is_login"] = "success" # 登錄成功將is_login的值設置success WHETHER_LOGIN["is_user"] = username # 將我們登錄的用戶放入字典用,方便後期查詢 # print(USER_LIST) return f_user_list else: print("登錄失敗") def main(): while True: global COUNT COUNT += 1 print("用戶管理系統".center(80, "*") + "\n") print("1、用戶登錄;2:用戶註冊;3:修改密碼;4:用戶信息;5:用戶管理;6:退出登錄;7:退出程式") inp = input("請輸入序號:") if inp == "1": if USER_LIST: if USER_LIST[3] == "1": print("當前為管理員用戶:【%s】,不能繼續登錄" % USER_LIST[0]) else: print("當前用戶為【%s】,不能繼續登錄" % USER_LIST[0]) else: login() elif inp == "2": register() elif inp == "3": alter() elif inp == "4": see() elif inp == "5": manage() elif inp == "6": exit_login() elif inp == "7": exit("程式已退出!!!") else: if COUNT == 3: exit("輸入錯誤次數過多,程式自動退出。。。") else: print("輸入有誤,請重新輸入。。。\n") continue main()