针对上一篇对文件的操作程序,执行一次操作的函数查询,添加,修改,删除都需要在函数里面定义文件处理的过程,整体函数看起来比较乱,代码重复过多
下面新定义一个函数专门用于处理文件操作,然后在不同的函数里面调用该函数
这种方法称为解耦
day21-2.py
#定义针对文件操作的函数把文件操作单独出来,通过type区分根据不同的调用方式处理不同的事情 def file_handler(backend_data,res=None,type='fetch'): if type == 'fetch': # 以只读方式打开文件如果遇到对应的关键行,这里的关键行是 backend www1则把标签置为True # 需要输出的是关键行和下一个关键行之间的数据,所以假如循环到下一个以backend开头的关键字则退出整个循环 # 假如遇到查询的关键行并且还没有遇到下一个以backend开头的关键行则tag值为True打印两行之间的数据 # 并且把数据追加到列表中作为返回值返回 with open('test.conf', 'r') as read_f: tag = False ret = [] for read_line in read_f: if read_line.strip() == backend_data: tag = True continue if tag and read_line.startswith('backend'): break if tag: print(read_line, end='') ret.append(read_line) return ret # 以只读方式打开文件test.conf以写方式打开新文件test.conf_new并且定义两个补签tag和has_write # tag补签用来识别是直接写原文件内容还是写新列表内容 # has_write补签用来识别列表内容是否已经写过一遍了,如果已经写过一遍就无需重复写入了 elif type == 'add': with open('test.conf', 'r') as read_f, open('test.conf_new', 'w') as wirte_f: tag = False has_write = False for read_line in read_f: if read_line.strip() == backend_data: tag = True continue if read_line.startswith('backend'): tag = False if not tag: wirte_f.write(read_line) else: if not has_write: for record in res: wirte_f.write(record) has_write = True elif type == 'change': with open('test.conf', 'r') as read_f, open('test.conf_new', 'w') as write_f: tag = False has_write = False for read_line in read_f: if read_line.strip() == backend_data: tag = True continue if tag and read_line.startswith('backend'): tag = False if not tag: write_f.write(read_line) else: if not has_write: for record in res: write_f.write(record) has_write = True elif type == 'delete': with open('test.conf', 'r') as read_f, open('test.conf_new', 'w') as write_f: tag = False has_write = False for read_line in read_f: if read_line.strip() == backend_data: tag = True continue if tag and read_line.startswith('backend'): tag = False if not tag: write_f.write(read_line) else: if not has_write: for record in res: write_f.write(record) has_write = True def fetch(data): print('这是查询函数,用户的输入是%s' %data) #data = 'www1' backend_data = 'backend %s' %data #backend_data = 'backend www1' return file_handler(backend_data) def add(data): print('这是添加函数,用户输入的数据是%s' %data) #data = [{'backend':'www1','server':'3'}] backend = data[0]['backend'] # backend = 'www1' backen_data = 'backend %s' % backend # backend_data = 'backend www1' res = fetch(backend) # res = [' server 1 ', ' server 2 ', ' '] add_server_record = '%sserver %s ' %(' '*4,data[0]['server']) #add_server_record = ' server 3 ' if not res: print('修改的数据不存在') elif add_server_record in res: print('需要修改的数据重复') else: res.insert(-1,add_server_record) #res = [' server 1 ', ' server 2 ', ' server 3 ',' '] res.insert(0,'%s ' %backen_data) #res = ['backend www1 ',' server 1 ', ' server 2 ', ' server 3 ',' '] file_handler(backen_data,res=res,type='add') def change(data): #data是一个特定格式的列表,前面包含了需要修改的旧数据的一个字典,后面包含了需要改成什么的字典 #因为input接收输入格式为字符串所以需要在输入数据的时候判定之前输入的选项如果不是1查询功能则需要把字符串通过eval函数方法转换成列表格式 print('这是修改函数,用户输入的数据是%s' % data) #data = [{'backend':'www1','server':'1'},{'backend':'www1','server':'3'}] #根据列表及字典索引取出需要查询的关键字www1 作为查询函数fetch的参数 backend = data[0]['backend'] #backend = 'www1' #根据需要查询的关键字加backend拼接出关键行 backend_data = 'backend %s' %backend #backend_data = 'backend www1' #根据取出的关键字www1查询并且把结果返回给一个列表res 这个列表作为一会修改时需要写入文件的以后列表 res = fetch(backend) # res = [' server 1 ', ' server 2 ', ' '] #根据用户输入取出需要修改的旧数据和需要修改成什么的新数据,需要加换行符 old_server_record = '%sserver %s ' %(' '*4,data[0]['server']) #old_server_record = ' server 1 ' new_server_record = '%sserver %s ' %(' '*4,data[1]['server']) #old_server_record = ' server 3 ' #判断调用查询函数fetch返回的列表res是否为空以及需要修改的旧数据是否在列表中,如果其中一条不成立及返回数据不存在 if not res or old_server_record not in res: print('需要修改的数据不存在') #如果满足以上条件res有返回值并且修改的旧数据在res里面则先找出就数据的索引然后根据索引把旧数据替换成需要修改的新数据 #因为res没有返回关键行的数据所以需要把关键行插入列表res中 else: index = res.index(old_server_record) #index=0 res[index] = new_server_record #res = [' server 3 ', ' server 2 ', ' '] res.insert(0,'%s ' %backend_data) #res = ['backend www1 ',' server 3 ', ' server 2 ', ' '] file_handler(backend_data,res=res,type='change') def delete(data): print('这是删除函数,用户输入的数据是%s' %data) #data = [{'server': '1', 'backend': 'www1'}] backend = data[0]['backend'] # backend = 'www1' backen_data = 'backend %s' % backend # backend_data = 'backend www1' res = fetch(backend) # res = [' server 1 ', ' server 2 ', ' '] del_server_record = '%sserver %s ' % (' ' * 4, data[0]['server']) # del_server_record = ' server 1 ' if not res or del_server_record not in res: print('需要删除的内容不存在') else: res.remove(del_server_record) #res = [' server 2 ', ' '] res.insert(0, '%s ' % backen_data) #res = ['backend www1 ',' server 2 ', ' '] file_handler(backen_data,res=res,type='delete') if __name__ == '__main__': #定义需要显示的信息 msg = ''' 1:查询 2:添加 3:修改 4:删除 5:退出 ''' #定义一个字典根据用户输入的选项以及输入的数据执行对应操作 msg_dic={ '1': fetch, '2': add, '3': change, '4': delete } while True: print(msg) choice = input('请输入选项:') #如果输入为空则退出本次循环重新输入 if choice == '':continue #如果输入为5则退出程序 if choice == '5':break data = input('请输入数据:') #如果不是选项1执行操作则需要把输入的字符串类型转换成对应的列表类型 if choice != '1': data = eval(data) #根据用户输入的choic和data数据执行对应的函数 res = msg_dic[choice](data) print('最终返回结果是%s' % res)