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

需求,有一个配置文件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
', '    server 2
', '
']

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
', '    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
' %backend_data)   #res = ['backend www1
','    server 1
', '    server 2
', '    server 3
','
']
    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
', '    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
', '
']
    #以只读方式打开文件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
', '    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
', '
']
    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)

  

原文地址:https://www.cnblogs.com/minseo/p/8350342.html