需求,有一个配置文件test.conf内容如下

backend www1
server 1
server 2 backend www2
server 3
server 4 add
[{'backend':'www1','server':'3'}]
change
[{'backend':'www1','server':'1'},{'backend':'www1','server':'3'}]
delete
[{'backend':'www1','server':'1'}]

  1,自定义函数实现查询功能,查询需要根据用户输入的关键字进行查询如输入www1则查询出对应的下面的配置

  2,自定义函数实现添加功能,比如在关键字www1后面添加一个配置为server 3

  3,自定义函数实现修改功能,比如把server 1修改成 server 3

  4,自定义函数实现删除功能,比如把www1后面的server 1删除

  

  day21-1.py

def fetch(data):
print('这是查询函数,用户的输入是%s' %data) #data = 'www1'
backend_data = 'backend %s' %data #backend_data = 'backend www1'
#以只读方式打开文件如果遇到对应的关键行,这里的关键行是 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 #ret = [' server 1\n', ' server 2\n', '\n'] def add(data):
print('这是添加函数,用户输入的数据是%s' %data) #data = [{'backend':'www1','server':'3'}]
backend = data[0]['backend'] # backend = 'www1'
backend_data = 'backend %s' % backend # backend_data = 'backend www1'
res = fetch(backend) # res = [' server 1\n', ' server 2\n', '\n']
add_server_record = '%sserver %s\n' %(' '*4,data[0]['server']) #add_server_record = ' server 3\n'
if not res:
print('修改的数据不存在')
elif add_server_record in res:
print('需要修改的数据重复')
else:
res.insert(-1,add_server_record) #res = [' server 1\n', ' server 2\n', ' server 3\n','\n']
res.insert(0,'%s\n' %backend_data) #res = ['backend www1\n',' server 1\n', ' server 2\n', ' server 3\n','\n']
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 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\n', ' server 2\n', '\n']
#根据用户输入取出需要修改的旧数据和需要修改成什么的新数据,需要加换行符\n
old_server_record = '%sserver %s\n' %(' '*4,data[0]['server']) #old_server_record = ' server 1\n'
new_server_record = '%sserver %s\n' %(' '*4,data[1]['server']) #old_server_record = ' server 3\n'
#判断调用查询函数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\n', ' server 2\n', '\n']
res.insert(0,'%s\n' %backend_data) #res = ['backend www1\n',' server 3\n', ' server 2\n', '\n']
#以只读方式打开文件test.conf以写方式打开新文件test.conf_new并且定义两个补签tag和has_write
#tag补签用来识别是直接写原文件内容还是写新列表内容
#has_write补签用来识别列表内容是否已经写过一遍了,如果已经写过一遍就无需重复写入了
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 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\n', ' server 2\n', '\n']
del_server_record = '%sserver %s\n' % (' ' * 4, data[0]['server']) # del_server_record = ' server 1\n'
if not res or del_server_record not in res:
print('需要删除的内容不存在')
else:
res.remove(del_server_record) #res = [' server 2\n', '\n']
res.insert(0, '%s\n' % backen_data) #res = ['backend www1\n',' server 2\n', '\n']
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() == backen_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 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)

  

Python全栈day21(作业针对一个文件进行查询修改删除的操作练习)的更多相关文章

  1. python 全栈开发,Day26(hashlib文件一致性,configparser,logging,collections模块,deque,OrderedDict)

    一.hashlib文件一致性校验 为何要进行文件一致性校验? 为了确保你得到的文件是正确的版本,而没有被注入病毒和木马程序.例如我们经常在网上下载软件,而这些软件已经被注入了一些广告和病毒等,如果不进 ...

  2. Python全栈-day6-day7-字符编码和文件处理

    一.字符编码 1.编码基础 定义:人在使用计算机时,使用的是人类能够读懂的字符,使用者必须通过一张字符和数字间的相对应关系表实现人机交互,这一系列标准称为字符编码 Python应用中解决核心字符串乱码 ...

  3. 巨蟒python全栈开发-第8天 文件操作

    一.文件操作 今日大纲: 1.文件操作->open() open 打开 f=open(文件路径,mode='模式',encoding='编码格式') #python最最底层操作的就是bytes ...

  4. python学习之老男孩python全栈第九期_day009之文件操作总结

    # 文件处理# 打开文件# open('路径','打开方式', '指定编码方式')# 打开方式:r w a 可读可写:r+ 可写可读:w+ 可追加可读:a+ b# r+ :打开文件直接写,和读完再写 ...

  5. 【Python全栈-HTML】HTML引入文件的绝对路径、相对路径、根目录

    HTML引入文件的绝对路径.相对路径.根目录 什么是绝对路径?绝对路径指的是文件的真正路径,使用绝对路径链接外部资源,如:图片.超级链接.flash.音频.视频等等.代码如下: 1.引入网络上的资源: ...

  6. Python全栈day21(调用模块路径BASEDIR的正确方法)

    正常写python程序会有一个可执行的bin.py文件,假如这个文件需要导入my_module里面定义的模块,应该怎么设置sys.path 文件夹目录结构如下,因为bin不在与my_module同级目 ...

  7. Python全栈day21(函数的解耦)

    针对上一篇对文件的操作程序,执行一次操作的函数查询,添加,修改,删除都需要在函数里面定义文件处理的过程,整体函数看起来比较乱,代码重复过多 下面新定义一个函数专门用于处理文件操作,然后在不同的函数里面 ...

  8. python全栈开发day51-jquery插件、@media媒体查询、移动端单位、Bootstrap框架

    一.昨日内容回顾 技术行业 (1)ajax技术 XMLHttpRequest() <1>创建XMLHttpRequest()对象 <2>检测状态(通过readyState的改变 ...

  9. 巨蟒python全栈开发django7:多表增加和查询

    1.回顾内容&&补充 补充1: 补充2: 这个选择的是第二个解释器. 选择第一个的话,只是针对当前的项目,如果再开新项目的话,需要重新下载安装相关的包. 点击保存,因为我们注释掉了,创 ...

随机推荐

  1. COM方式实现C++调用C#代码的一些总结

    首先这个测试没成功,只在本机上可行,在不同机器上测试失败.可能是GUID不对或者没注册成功. 既然已经花了一上午时间去研究,还是总结一下 1.网上说要创建一个snk证书,但不创建也可以.只不过不能放入 ...

  2. Atitit.基于时间戳的农历日历历法日期计算

    Atitit.基于时间戳的农历日历历法日期计算 1. 农历xx年的大小月份根据万年历查询1 2. 农历xx年1月1日的时间戳获取1 3. 计算当年的时间戳与农历日期的对应表,时间戳为key,日期为va ...

  3. Xilinx-7Series-FPGA高速收发器使用学习—RX接收端介绍

    上一篇博文介绍了GTX的发送端,这一篇将介绍GTX的RX接收端,GTX RX接收端的结构和TX发送端类似,数据流方向相反,不过和发送端也有一些区别,GTX的RX接收端结构图如图1所示: 图1 下面将根 ...

  4. windows gvim插入当前时间

    :nnoremap <F5> "=strftime("%c")<CR>P :inoremap <F5> <C-R>=str ...

  5. forward declaration of class 错误

    在使用Qt的时候遇到这个错误,查了一下发现,是因为我没有正确的使用前置声明. #ifndef FIRSTPAGE_H #define FIRSTPAGE_H #include "ui_dia ...

  6. linux下挂载win7的共享文件夹

    由于跨平台开发的需要,需要在Linux和windows之间共享文件夹,所以找了一下方法,我试验了两种都可以使用. 首先声明一下我使用的是VMware10.CentOS6.2 一.手动操作 1.按照下图 ...

  7. 【转载】PHP 常用的header头部定义汇总

    header() 函数向客户端发送原始的 HTTP 报头. 认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此 ...

  8. 跟着百度学PHP[12]-文件处理 文件 目录

    00x1 文件的属性 文件属性 <?php //-------------------------定义大小转换函数--------------- function changesize_dw($ ...

  9. [开机启动]Linux开机自启和运行级别

    嵌入式系统中程序自启动方法 在很多嵌入式系统中,由于可用资源较少,常常在系统启动后就直接让应用程序自动启动,以减少用户操作和节省资源.如何让自己的应用程序自动启动呢?    在Linux系统中,配置应 ...

  10. PHP——动态随机数

    取1-13随机数 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...