2017python第三天作业
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017python第三天作业相关的知识,希望对你有一定的参考价值。
这个作业是包含了循环,函数,文件修改,列表,字典等等的知识点
首先需要改的文件是Haproxy的配置文件
![技术分享](/img/jia.gif)
global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 info defaults log global mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option dontlognull listen stats :8888 stats enable stats uri /admin stats auth admin:1234 frontend oldboy.org bind 0.0.0.0:80 option httplog option httpclose option forwardfor log global acl www hdr_reg(host) -i www.oldboy.org use_backend www.oldboy.org if www backend www.oldboy.org server 100.1.7.10 100.1.7.10 weight 20 maxconn 3000 backend www.baidu.com server 100.1.7.11 100.1.7.11 weight 20 maxconn 3000
这个是一个参考的代码
![技术分享](/img/jia.gif)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author: Even 4 5 6 import os,sys 7 8 9 def numif(number_input): # 判断输入是否为数字 10 while not number_input.isdigit(): # 输入不是数字就进入循环 11 number_input = input(‘\033[31m 输入%s不是数字,请重新输入!\033[0m‘ % number_input) # 提示重新输入 12 number = number_input 13 return number 14 15 16 def show_list(file): # 查询显示并将文本生成程序需要的字典和列表 17 backend_list = [] 18 backend_all_dict = {} 19 backend_dict = {} 20 server_list = [] 21 with open(file,‘r‘) as f: # 读取haproxy文件 22 for line in f: 23 24 line = line.strip() 25 if line.startswith(‘backend‘) == True: # 判断是否是backend开头,读取backend信息写到backend_list中 26 backend_name = line.split()[1] 27 backend_list.append(backend_name) # 将文件中backend加到列表中 28 server_list = [] # 清空server_list里的记录,遇到新backend可以输入新的server_list 29 30 elif line.startswith(‘server‘) == True: # 判断是否是server开头,读取server信息写到backend_all_dict中 31 backend_dict[‘name‘] = line.split()[1] # 读取文件中server的name 32 backend_dict[‘IP‘] = line.split()[2] # 读取文件中server的IP 33 backend_dict[‘weight‘] = line.split()[4] # 读取文件中server的weight 34 backend_dict[‘maxconn‘] = line.split()[6] # 读取文件中server的maxconn 35 server_list.append(backend_dict.copy()) # 将backend中的信息加到server_list中,此处需要用copy 36 backend_all_dict[backend_name] = server_list # 将server信息对应backend存到字典中 37 38 return (backend_list,backend_all_dict) # 返回backend和server信息 39 40 41 def backend_show(backend_list): # 展示backend列表内容 42 backend_show_dict = {} 43 print("-------------------------------------------------") 44 print("\t\t\t欢迎来到HAproxy文件配置平台") 45 print("-------------------------------------------------") 46 print("backend列表信息如下:") 47 for k,v in enumerate(backend_list,1): # 逐行读取backend信息并展示 48 print(k, v) 49 backend_show_dict[str(k)] = v 50 return backend_show_dict # 返回backend和对应编号 51 52 53 def server_show(backend_input,backend_all_dict): # 展示backend下server内容 54 server_show_dict = {} 55 server_list = backend_all_dict[backend_input] 56 for k,v in enumerate(server_list,1): # 编号展示server信息 57 print(k,"name:",v[‘name‘],"\tIP:",v[‘IP‘],"\tweight:",v[‘weight‘],"\tmaxconn:",v[‘maxconn‘]) 58 server_show_dict[k] = v 59 return server_show_dict # 返回编号对应的server字典 60 61 62 def action_list(): # 显示操作列表和编号,并返回操作编号 63 print("-------------------------------------------------") 64 print("操作清单如下:") 65 print(‘‘‘ 66 1.查询backend和server信息 67 2.添加backend和server信息 68 3.修改backend和server信息 69 4.删除backend和server信息 70 5.退出 71 ‘‘‘) 72 print("-------------------------------------------------") 73 action_num = numif(input("请输入需要操作的编号:(请输入数字)")) 74 return action_num 75 76 77 def inquiry(inquiry_input): # 定义查询功能 78 while True: 79 if inquiry_input in backend_show_dict: # 编号输入分支 80 backend_input = backend_show_dict[inquiry_input] # 输入编号得到backend 81 print(backend_input, ":") 82 server_show(backend_input, backend_all_dict) # 调用server_show,展示backend下server 83 break 84 85 elif inquiry_input in backend_show_dict.values(): # backend名称输入分支 86 print(inquiry_input, ":") 87 server_show(inquiry_input, backend_all_dict) # 调用server_show,展示backend下server 88 break 89 90 else: # 校验异常输入 91 inquiry_input = input("输入错误,请重新输入:") 92 93 94 def add(add_input,file): # 定义添加功能 95 (backend_list, backend_all_dict) = show_list(file) 96 while True: 97 if add_input in backend_show_dict: #添加原有backend下server 98 add_dict = {} 99 add_dict[‘name‘] = input("请输入需增加server名称:") 100 add_dict[‘IP‘] = input("请输入需增加IP地址:") 101 add_dict[‘weight‘] = input("请输入需增加weight值:") 102 add_dict[‘maxconn‘] = input("请输入需增加maxcoon值:") 103 backend_name_add = backend_list[int(add_input)-1] 104 105 for dict in backend_all_dict[backend_name_add]: # 实现IP已存在,更新weight信息和maxconn信息 106 if add_dict[‘IP‘] in dict.values(): 107 dict[‘weight‘] = add_dict[‘weight‘] 108 dict[‘maxconn‘] = add_dict[‘maxconn‘] 109 break 110 111 else: # IP不存在,就将server增加到backend下 112 backend_all_dict[backend_name_add].append(add_dict) 113 114 backup(file,backend_name_add,backend_all_dict) # 调用backup函数,将新增内容读写到文件中 115 print(‘‘‘name:%s IP:%s weight:%s maxconn:%s已添加成功‘‘‘%( 116 add_dict[‘name‘],add_dict[‘IP‘],add_dict[‘weight‘],add_dict[‘maxconn‘])) # 提示添加成功 117 break 118 119 else: # 添加新backend下的server 120 add_dict = {} 121 add_dict[‘name‘] = input("请输入%s下新增server名称:"%add_input) 122 add_dict[‘IP‘] = input("请输入%s下新增IP地址:"%add_input) 123 add_dict[‘weight‘] = input("请输入%s下新增weight值:"%add_input) 124 add_dict[‘maxconn‘] = input("请输入%s下新增maxcoon值:"%add_input) 125 backend_name_add = add_input 126 backend_all_dict[backend_name_add] = add_dict # 将新增backend和对应server存到字典中 127 128 file_new = "%s_new" % file # 新建一个文件,用来新增数据 129 with open(file, ‘r‘) as f_read, open(file_new, ‘a+‘) as f_write: # 读取file文件,追加backend信息 130 for line in f_read: 131 f_write.write(line) 132 f_write.write("\nbackend %s" % backend_name_add) # 追加backend信息 133 server_line_write = ‘\n\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ # 追加server信息 134 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 135 136 os.system(‘mv %s %s_backup‘ % (file, file)) # 将file文件名改为file_backup 137 os.system(‘mv %s %s‘ % (file_new, file)) # 将file_new文件名改为file,实现备份 138 print("\nbackend %s" % backend_name_add) 139 print(‘‘‘name:%s IP:%s weight:%s maxconn:%s已添加成功‘‘‘ % ( 140 add_dict[‘name‘], add_dict[‘IP‘], add_dict[‘weight‘], add_dict[‘maxconn‘])) # 提示添加成功 141 break 142 143 144 def revise(revise_input): # 定义修改功能 145 revise_dict = {} 146 if revise_input in backend_show_dict: # 判断输入是否存在 147 backend_revise = backend_show_dict[revise_input] # 通过编号获取backend 148 revise_choise = input("是否需要修改该backend名称:%s;确认请按‘y‘,按任意键继续:"%backend_revise) # 确认是否修改backend名,输入y修改,否则继续修改 149 if revise_choise == ‘y‘: 150 backend_revise_new = input("请输入修改后的backend名:") # 修改backend名 151 backend_all_dict[backend_revise_new] = backend_all_dict.pop(backend_revise) # 将旧backend的server对应到修改后的backend上 152 revise_choise_server = input("是否需要继续修改%s下的server:确认请按‘y‘,按任意键继续:"%backend_revise_new) # 询问是否继续修改 153 if revise_choise_server == ‘y‘: # 继续修改server 154 server_revise_dict = server_show(backend_revise_new, backend_all_dict) # 展示server信息 155 server_revise_num = numif(input("请输入需要修改的server编号:")) # 获取需要修改的server编号 156 revise_dict[‘name‘] = input("请输入修改后的name:") 157 revise_dict[‘IP‘] = input("请输入修改后的IP:") 158 revise_dict[‘weight‘] = input("请输入修改后的weight:") 159 revise_dict[‘maxconn‘] = input("请输入修改后的maxconn:") 160 server_revise_dict[int(server_revise_num)] = revise_dict # 通过编号修改server信息 161 server_revise_dict_backup = {} 162 server_revise_dict_backup[backend_revise_new] = server_revise_dict.values() # 将修改的server信息对应到修改后的backend存到字典中 163 backup(file, backend_revise, server_revise_dict_backup,backend_revise_new) # 调用backup函数,操作文件 164 165 else: # 不修改server,只修改了backend 166 backup(file, backend_revise, backend_all_dict,backend_revise_new) 167 else: # 未修改backend名情况时修改server信息 168 server_revise_dict = server_show(backend_revise, backend_all_dict) 169 server_revise_num = numif(input("请输入需要修改的server编号:")) # 获取需修改的server编号 170 revise_dict[‘name‘] = input("请输入修改后的name:") 171 revise_dict[‘IP‘] = input("请输入修改后的IP:") 172 revise_dict[‘weight‘] = input("请输入修改后的weight:") 173 revise_dict[‘maxconn‘] = input("请输入修改后的maxconn:") 174 server_revise_dict[int(server_revise_num)] = revise_dict # 修改的server信息对应到编号中存到字典中 175 server_revise_dict_backup = {} 176 server_revise_dict_backup[backend_revise] = server_revise_dict.values() # 将修改后的server信息对应backend存到字典中 177 backup(file,backend_revise,server_revise_dict_backup) # 调用backup函数,操作文件 178 else: # 输入错误提示重新输入 179 revise_input_return = input("需修改backend不存在,请重新输入:") 180 revise(revise_input_return) 181 182 183 def delete(delete_input): # 定义删除功能 184 if delete_input in backend_show_dict: 185 backend_delete = backend_show_dict[delete_input] 186 delete_choise = input("是否需要删除该backend:%s;确认请按‘y‘,按任意键继续:"%backend_delete) 187 if delete_choise == ‘y‘: # 判断是否删除backend信息 188 del backend_all_dict[backend_delete] # 在backend与server总字典中删除backend 189 backup(file, backend_delete, backend_all_dict) # 调用backup函数,操作文件 190 191 else: # 删除server 192 server_delete_dict = server_show(backend_delete, backend_all_dict) 193 server_delete_num = int(numif(input("请输入需要删除的server编号:"))) # 除判断是否时数字外,还需转换为整数型 194 while True: # 删除backend下的server循环 195 if server_delete_num in server_delete_dict: # 判断输入编号是否存在 196 server_delete_dict.pop(server_delete_num) 197 server_delete_dict_backup = {} 198 server_delete_dict_backup[backend_delete] = server_delete_dict.values() 199 backup(file, backend_delete, server_delete_dict_backup) # 调用backup函数,操作文件 200 break 201 else: 202 server_delete_num = input("输入编号不存在,请重新输入:") # 提示输入错误 203 204 205 def backup(file,backend_name_action,backend_backup_dict,*backend_name_revise): # 定义文档备份与回写功能 206 file_new = "%s_new"%file 207 add_flag = False # 为跳过原backend下server存在 208 with open(file,‘r‘) as f_read , open(file_new,‘w+‘) as f_write: # 同时打开读文件和写文件 209 for line in f_read: # 读取每行信息 210 backend_name = "backend %s" % backend_name_action 211 backend_name_revise = "".join(tuple(backend_name_revise)) # 修改功能会传参,将元组转换为字符串 212 if line.strip() == backend_name: # 读取某行中有参数中的backend 213 if backend_name_action not in backend_backup_dict and backend_name_revise not in backend_backup_dict: # 为了删除backend而存在 214 add_flag = True 215 pass 216 217 elif backend_name_revise in backend_backup_dict: # 判断修改功能中修改后backend存在与字典中 218 line_revise = "backend %s\n" % backend_name_revise 219 f_write.write(line_revise) 220 for add_dict in backend_backup_dict[backend_name_revise]: # 逐行读取修改backend下的server信息 221 server_line_write = ‘\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ 222 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 223 add_flag = True 224 225 else: 226 f_write.write(line) # 将此行写在文件中 227 for add_dict in backend_backup_dict[backend_name_action]: # 读取该backend下所有server信息 228 server_line_write = ‘\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ 229 f_write.write(server_line_write.format(**add_dict)) 230 add_flag = True 231 232 elif line.strip().startswith("server") == True and add_flag == True: # 为了跳过原backend下的server 233 pass 234 235 else: # 写无用行 236 f_write.write(line) 237 add_flag = False # 写下无用行后可以继续循环 238 239 os.system(‘mv %s %s_backup‘ % (file, file)) 240 os.system(‘mv %s %s‘ % (file_new, file)) 241 242 243 def backend_exit(): #定义退出功能 244 flag_exit = True 245 b_input = input("操作完毕退出请按‘b‘:") 246 while flag_exit: 247 if b_input == ‘b‘: 248 flag_exit = False 249 return flag_exit 250 251 else: 252 return backend_exit() #使用尾递归优化,加上return帮助直接退出,而不需要递归一层层退出 253 254 255 flag = True # 主函数开始 256 while flag: 257 flag_main = True 258 flag_action = True 259 file = ‘haproxy‘ # 文件名赋值 260 (backend_list, backend_all_dict) = show_list(file) # 调用show_list函数获取backend和server信息 261 backend_show_dict = backend_show(backend_list) # 展示backend信息 262 action_num = action_list() # 展示功能项,并输入操作编号 263 while flag_main: 264 if action_num == ‘1‘: 265 inquiry(input("请输入需要查询的backend编号或名称:")) 266 flag_main = backend_exit() 267 break 268 269 if action_num == ‘2‘: 270 add(input("请输入需要添加的现有backend编号或新backend名称:"), file) 271 flag_main = backend_exit() 272 break 273 274 if action_num == ‘3‘: 275 revise(input("请输入需要修改的backend编号或名称:")) 276 flag_main = backend_exit() 277 break 278 279 if action_num == ‘4‘: 280 delete(input("请输入需要删除的backend编号或名称:")) 281 flag_main = backend_exit() 282 break 283 284 if action_num == ‘5‘: 285 sys.exit() 286 287 elif action_num not in range(5): # 当输入不在编号中,提示并重新输入 288 print("\033[31;1m输入错误请重新输入!\033[0m") 289 flag_main = False
主要的思想是先办法把需要拿到的数据变成字典或者列表,让后通过增删改查的方式把列表或者字典改成需要的样子,然后再按照格式把字典或者列表写入到另外一个文件中。
然后再把新的文件替换掉现有的文件就可以完成任务了
中间要主要函数的实用,尽量把过程分开化,合理的定义每个功能的函数再调用。(这个是重点)
以上是关于2017python第三天作业的主要内容,如果未能解决你的问题,请参考以下文章