Python 模擬員工信息數(shù)據(jù)庫操作的實(shí)例
1.功能簡介
此程序模擬員工信息數(shù)據(jù)庫操作,按照語法輸入指令即能實(shí)現(xiàn)員工信息的增、刪、改、查功能。
2.實(shí)現(xiàn)方法
• 架構(gòu):
本程序采用python語言編寫,關(guān)鍵在于指令的解析和執(zhí)行:其中指令解析主要運(yùn)用了正則表達(dá)式來高效匹配有效信息;指令執(zhí)行通過一個(gè)commd_exe主執(zhí)行函數(shù)和增、刪、改、查4個(gè)子執(zhí)行函數(shù)來實(shí)現(xiàn),操作方法主要是運(yùn)用面向?qū)ο蠓椒▽T工信息對象化,從而使各項(xiàng)操作都能方便高效實(shí)現(xiàn)。程序主要函數(shù)如下:
(1)command_exe(command)
指令執(zhí)行主函數(shù),根據(jù)指令第一個(gè)字段識別何種操作,并分發(fā)給相應(yīng)的處理函數(shù)執(zhí)行。
(2)add(command)
增加員工記錄函數(shù),指令中需包含新增員工除id號以外的其他所有信息,程序執(zhí)行后信息寫入員工信息表最后一行,id號根據(jù)原最后一條記錄的id號自增1。
(3)delete(command)
刪除員工記錄函數(shù),可根據(jù)where后的條件檢索需刪除的記錄,并從信息表中刪除。
(4)update(command)
修改和更新員工記錄函數(shù),根據(jù)where后的條件檢索需更新的記錄,根據(jù)set后的等式修改和更新指定的信息。
(5)search(command)
查詢員工記錄函數(shù),根據(jù)where后的條件查詢到相應(yīng)的記錄,根據(jù)select后的關(guān)鍵字來顯示記錄的指定信息,如果為*顯示記錄的所有信息。
(6)verify(staff_temp,condition)
員工信息驗(yàn)證函數(shù),傳入一個(gè)對象化的員工記錄和指令中where后的條件字符串,判斷記錄是否符合條件,符合在返回True,否則返回False。指令包含where字段的刪、改、查操作會調(diào)用此函數(shù)。
(7)logic_cal(staff_temp,logic_exp)
單個(gè)邏輯表達(dá)式的運(yùn)算函數(shù),傳入一個(gè)對象化的員工記錄和從where條件字符串中被and、or、not分割的單個(gè)表達(dá)式,實(shí)現(xiàn)=,>,<,>=,<=,like等確定的一個(gè)邏輯表達(dá)式的運(yùn)算,返回結(jié)果為True或False。
• 主要操作:
數(shù)據(jù)記錄包含6個(gè)關(guān)鍵字:id,name,age,phone,dept,enroll_date
指令可用的邏輯運(yùn)算符:<,>,=,<=,>=,like,and,or,not
數(shù)據(jù)庫操作:
1.增(add to xxxx values xxxx)
示例:add to staff_table values Alex Li,22,13651054608,IT,2013-04-01
2.刪(delete from xxxx where xxxx)
示例:delete from staff_table where age<=18 and enroll_date like "2017"
3.改(update xxxx set xxxx where xxxx)
示例:
update staff_table set dept="Market",age=30 where dept="IT" and phone like "189"
4.查(select xxxx from xxxx where xxxx)
示例1:
select * from staff_table where age>=25 and not phone like "136" or name like "李"
示例2:
select name,age,dept from db.txt where id<9 and enroll_date like "-05-"
示例3:select * from staff_table where * #顯示所有記錄
•使用文件:
staff_table
存放員工信息表,作為模擬的數(shù)據(jù)庫文件,每條記錄包含id,name,age,phone,dept,enroll_date六項(xiàng)信息,如"1,Alex Li,22,13651054608,IT,2013-04-0"。
3.流程圖

4.代碼
#!usr/bin/env python3
#_*_coding:utf-8_*_
'staff infomation management module'
__author__='Byron Li'
'''----------------------------------------------員工信息數(shù)據(jù)庫操作指令語法---------------------------------------------
數(shù)據(jù)記錄包含6個(gè)關(guān)鍵字:id,name,age,phone,dept,enroll_date
指令可用的邏輯運(yùn)算符:<,>,=,<=,>=,like,and,or,not
1.增(add to xxxx values xxxx)
示例:add to staff_table values Alex Li,22,13651054608,IT,2013-04-01
2.刪(delete from xxxx where xxxx)
示例:delete from staff_table where age<=18 and enroll_date like "2017"
3.改(update xxxx set xxxx where xxxx)
示例:update staff_table set dept="Market",age=30 where dept="IT" and phone like "189"
4.查(select xxxx from xxxx where xxxx)
示例1:select * from staff_table where age>=25 and not phone like "136" or name like "李"
示例2:select name,age,dept from db.txt where id<9 and enroll_date like "-05-"
示例3:select * from staff_table where * #顯示所有記錄
---------------------------------------------------------------------------------------------------------------------'''
import re
import os
class staff(object): #員工類
def __init__(self,*args): #員工信息初始化:從字符串列表傳參賦值
self.id=args[0]
self.name=args[1]
self.age=args[2]
self.phone=args[3]
self.dept=args[4]
self.enroll_date=args[5]
self.allinfo=','.join(args)
def update(self,**kwargs): #員工信息更新:從字典傳參賦值
if 'id' in kwargs:
self.id=kwargs['id']
if 'name' in kwargs:
self.name=kwargs['name']
if 'age' in kwargs:
self.age = kwargs['age']
if 'phone' in kwargs:
self.phone=kwargs['phone']
if 'dept' in kwargs:
self.dept=kwargs['dept']
if 'enroll_date' in kwargs:
self.enroll_date = kwargs['enroll_date']
self.allinfo = ','.join(map(str,[self.id, self.name, self.age, self.phone, self.dept, self.enroll_date]))
def print_info(self,info): #員工信息打印顯示:傳入的參數(shù)為"*"或數(shù)據(jù)記錄的若干個(gè)關(guān)鍵字
if info=='*':
print(self.allinfo)
else:
info=info.split(',')
res=[]
for i in info:
if hasattr(self,i.strip()):
res.append(str(getattr(self,i.strip())))
print(','.join(res))
def command_exe(command): #指令執(zhí)行主函數(shù),根據(jù)指令第一個(gè)字段識別何種操作,并分發(fā)給相應(yīng)的處理函數(shù)執(zhí)行
command=command.strip()
return {
'add':add,
'delete':delete,
'update':update,
'select':search,
}.get(command.split()[0],error)(command)
def error(command): #錯誤提示函數(shù),指令不合語法調(diào)用該函數(shù)報(bào)錯
print('\033[31;1m語法錯誤,請重新輸入!\033[0m\n')
def add(command): #增加員工記錄函數(shù)
command_parse=re.search(r'add\s*?to\s(.*?)values\s(.*)',command) #正則表達(dá)式指令解析
if(command_parse):
data_file=command_parse.group(1).strip() #數(shù)據(jù)庫文件
info=command_parse.group(2).strip() #需新增的員工信息,不含id
id=1 #新增員工id,默認(rèn)為1以防數(shù)據(jù)庫為空表時(shí)新增記錄id取1
with open(data_file, 'r+', encoding='utf-8') as fr:
line=fr.readline()
while(line):
if line.strip()=='':
fr.seek(fr.tell()-len(line)-2) #定位文件最后一行(只有空字符)的開頭
break
staff_temp = staff(*line.strip().split(',')) #讀取的信息轉(zhuǎn)換為staff對象
id = int(staff_temp.id) + 1 #末行員工id加1為新員工id
line = fr.readline()
info_new=''.join([str(id),',',info]) #id與其他信息合并成完整記錄
fr.write(info_new)
fr.write('\n')
fr.flush()
print("數(shù)據(jù)庫本次\033[31;1m新增1條\033[0m員工信息:", info_new) #新增記錄打印
else:
error(command)
def delete(command): #刪除員工記錄函數(shù)
command_parse=re.search(r'delete\s*?from\s(.*?)where\s(.*)',command) #指令解析
if(command_parse):
data_file=command_parse.group(1).strip() #數(shù)據(jù)庫文件
condition=command_parse.group(2).strip() #檢索條件
data_file_bak = ''.join([data_file, '.bak'])
count = 0 #刪除記錄計(jì)數(shù)
staff_list = [] #刪除記錄的員工對象列表
with open(data_file, 'r', encoding='utf-8') as fr, \
open(data_file_bak, 'w', encoding='utf-8') as fw:
for line in fr:
staff_temp = staff(*line.strip().split(','))
if (verify(staff_temp, condition)): #驗(yàn)證員工信息是否符合條件
count+=1
staff_list.append(staff_temp)
continue
fw.write(staff_temp.allinfo)
fw.write('\n')
fw.flush()
os.remove(data_file)
os.rename(data_file_bak, data_file)
print("數(shù)據(jù)庫本次共\033[31;1m刪除%d條\033[0m員工信息,如下:"%count)
for staff_temp in staff_list:
staff_temp.print_info('*') #刪除記錄打印
else:
error(command)
def update(command): #修改和更新員工記錄函數(shù)
command_parse=re.search(r'update\s(.*?)set\s(.*?)where\s(.*)',command) #指令解析
if(command_parse):
data_file=command_parse.group(1).strip() #數(shù)據(jù)庫文件
info=command_parse.group(2).strip() #需更新的信息
condition=command_parse.group(3).strip() #檢索條件
data_file_bak=''.join([data_file,'.bak'])
info = ''.join(['{', info.replace('=', ':'), '}']) #將需更新的信息按字典格式修飾字符串
info = eval(re.sub(r'(\w+)\s*:', r'"\1":', info)) #將字符串進(jìn)一步修飾最終轉(zhuǎn)化成字典
count = 0
staff_list = []
with open(data_file,'r',encoding='utf-8') as fr,\
open(data_file_bak,'w',encoding='utf-8') as fw:
for line in fr:
staff_temp=staff(*line.strip().split(','))
if(verify(staff_temp,condition)): #驗(yàn)證員工信息是否符合條件
staff_temp.update(**info) #調(diào)用員工對象成員函數(shù)更新信息
count += 1
staff_list.append(staff_temp)
fw.write(staff_temp.allinfo)
fw.write('\n')
fw.flush()
os.remove(data_file)
os.rename(data_file_bak,data_file)
print("數(shù)據(jù)庫本次共\033[31;1m更新%d條\033[0m員工信息,如下:"%count)
for staff_temp in staff_list:
staff_temp.print_info('*') #更新記錄打印
else:
error(command)
def search(command): #查詢員工記錄函數(shù)
command_parse=re.search(r'select\s(.*?)from\s(.*?)where\s(.*)',command) #指令解析
if(command_parse):
info=command_parse.group(1).strip() #檢索結(jié)束后需顯示的信息,"*"為顯示整體記錄
data_file=command_parse.group(2).strip() #數(shù)據(jù)庫文件
condition=command_parse.group(3).strip() #檢索條件
count = 0
staff_list = []
with open(data_file,'r',encoding='utf-8') as fr:
for line in fr:
staff_temp=staff(*line.strip().split(','))
if(verify(staff_temp,condition)): #驗(yàn)證員工信息是否符合條件
count += 1
staff_list.append(staff_temp)
print("數(shù)據(jù)庫本次共\033[31;1m查詢到%d條\033[0m員工信息,如下:" % count)
for staff_temp in staff_list:
staff_temp.print_info(info) #查詢記錄打印
else:
error(command)
def verify(staff_temp,condition): #員工信息驗(yàn)證函數(shù),傳入一個(gè)員工對象和條件字符串
if condition.strip()=='*':return True #如果條件為'*',即所有記錄都滿足條件
condition_list=condition.split() #檢索條件字符串轉(zhuǎn)列表
if len(condition_list)==0:return False
logic_str=['and','or','not'] #邏輯運(yùn)算字符串 且、或、非
logic_exp=[] #單個(gè)條件的邏輯表達(dá)式組成的列表,形如[‘a(chǎn)ge',' ','>','=',20] 或 [‘dept',' ','like',' ','HR']
logic_list=[] #每個(gè)條件的表達(dá)式的計(jì)算結(jié)果再重組后的列表,形如 [‘True','and','False','or','not','False']
for i in condition_list:
if i in logic_str:
if(len(logic_exp)!=0):
logic_list.append(str(logic_cal(staff_temp,logic_exp))) #邏輯表達(dá)式計(jì)算并將返回的True或False轉(zhuǎn)化成字符串添加到列表
logic_list.append(i)
logic_exp=[]
else:
logic_exp.append(i)
logic_list.append(str(logic_cal(staff_temp, logic_exp)))
return eval(' '.join(logic_list)) #列表轉(zhuǎn)化成數(shù)學(xué)表達(dá)式完成所有條件的綜合邏輯運(yùn)算,結(jié)果為True或False
def logic_cal(staff_temp,logic_exp): #單個(gè)邏輯表達(dá)式的運(yùn)算函數(shù)
logic_exp = re.search('(.+?)([=<>]{1,2}|like)(.+)',''.join(logic_exp)) #表達(dá)式列表優(yōu)化成三個(gè)元素,形如[‘a(chǎn)ge','>=',20] 或 [‘dept','like','HR']
if(logic_exp):
logic_exp=list(logic_exp.group(1,2,3))
if(hasattr(staff_temp,logic_exp[0])):
logic_exp[0] = getattr(staff_temp,logic_exp[0])
else:
return False
if logic_exp[1]=='=': #指令中的'='轉(zhuǎn)化成程序中相等判別的"=="
logic_exp[1]='=='
if logic_exp[1]=='like': #運(yùn)算符為like的表達(dá)式運(yùn)算
return re.search(logic_exp[2].strip("'").strip('"'),logic_exp[0]) and True
elif(logic_exp[0].isdigit() and logic_exp[2].isdigit()): #兩頭為數(shù)字的運(yùn)算,直接eval函數(shù)轉(zhuǎn)數(shù)學(xué)表達(dá)式
return eval(''.join(logic_exp))
elif(logic_exp[1]=='=='): #非數(shù)字的運(yùn)算,即字符串運(yùn)算,此時(shí)邏輯符只可能是‘=',若用eval函數(shù)則字符串會轉(zhuǎn)成無定義變量而無法計(jì)算,所以拿出來單獨(dú)用"=="直接計(jì)算
return logic_exp[0]==logic_exp[2].strip("'").strip('"') #字符串相等判別,同時(shí)消除指令中字符串引號的影響,即輸引號會比記錄中的字符串多一層引號
else: #其他不合語法的條件格式輸出直接返回False
return False
else:
return False
if __name__=='__main__': #主函數(shù),數(shù)據(jù)庫指令輸入和執(zhí)行
while(True):
command=input("請按語法輸入數(shù)據(jù)庫操作指令:") #指令輸入
if command=='exit':
print("數(shù)據(jù)庫操作結(jié)束,成功退出!".center(50, '*'))
break
command_exe(command) #指令執(zhí)行
以上這篇Python 模擬員工信息數(shù)據(jù)庫操作的實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- python3 實(shí)現(xiàn)爬取TOP500的音樂信息并存儲到mongoDB數(shù)據(jù)庫中
- python爬取cnvd漏洞庫信息的實(shí)例
- Python使用pyshp庫讀取shapefile信息的方法
- Python3爬蟲學(xué)習(xí)之MySQL數(shù)據(jù)庫存儲爬取的信息詳解
- Python實(shí)現(xiàn)的查詢mysql數(shù)據(jù)庫并通過郵件發(fā)送信息功能
- python用來獲得圖片exif信息的庫實(shí)例分析
- Python讀取圖片EXIF信息類庫介紹和使用實(shí)例
- 使用python BeautifulSoup庫抓取58手機(jī)維修信息
- 基于python3抓取pinpoint應(yīng)用信息入庫
相關(guān)文章
Python數(shù)據(jù)結(jié)構(gòu)樹與算法分析
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)樹與算法分析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
Python使用ffmpy將amr格式的音頻轉(zhuǎn)化為mp3格式的例子
今天小編就為大家分享一篇Python使用ffmpy將amr格式的音頻轉(zhuǎn)化為mp3格式的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列
這篇文章主要介紹了jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
使用Python的package機(jī)制如何簡化utils包設(shè)計(jì)詳解
這篇文章主要給大家介紹了關(guān)于使用Python的package機(jī)制如何簡化utils包設(shè)計(jì)的相關(guān)資料,文中通過示例代碼的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-12-12
python函數(shù)指定默認(rèn)值的實(shí)例講解
在本篇內(nèi)容里小編給大家整理了一篇關(guān)于python函數(shù)指定默認(rèn)值的實(shí)例講解內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)參考下。2021-03-03
python基礎(chǔ)之包的導(dǎo)入和__init__.py的介紹
這篇文章主要介紹了python基礎(chǔ)之包的導(dǎo)入和__init__.py的相關(guān)資料,需要的朋友可以參考下2018-01-01
利用Python構(gòu)建Flutter應(yīng)用的教程詳解
Flutter在軟件研發(fā)領(lǐng)域是非常流行的,今天就讓我們深入了解一下,用?Python構(gòu)建flutter應(yīng)用程序的世界,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12
基于python requests selenium爬取excel vba過程解析
這篇文章主要介紹了基于python requests selenium爬取excel vba過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

