zoukankan      html  css  js  c++  java
  • 文件的查询、修改实例+tag的用法++函数+程序的解耦

    #1.查找:从文件中找到www.oldboy1.org对应的backend记录并打印出相应的backend块
    
    ##################文件haproxy.conf中某个backend段落##########################
    backend www.oldboy1.org
            server 101.1000.7.9 101.1000.7.9 weight 20 maxconn 30
            server 2.2.2.7 2.2.2.7 weight 30 maxconn 4000
            server 10.10.10.1 10.10.10.1 weight 22 maxconn 2000
            server 2.2.2.5 2.2.2.5 weight 30 maxconn 4000
    ##############################################################
    
    import os
    # 程序的解耦:  把fetch和change的文件处理部分都合并到一起。一起来处理。增加代码可读性(注意函数的参数要传完整)
    def file_handler(backend_data,res=None,type='fetch'):  #fetch就可以不传res和type了
        if type == 'fetch':                                #查询功能
            with open('haproxy.conf','r') as read_f:
                tag=False        #如果没被改,那完全没有必要管它
                ret=[]            #为了使得fetch函数能够被别的功能调用。利用fetch函数返回值来给别的函数调用,用一个空列表存fetch查到的backend块
                for read_line in read_f:
                    if read_line.strip() == backend_data:      #找到了,将tag变true    #strip()默认去掉每行收尾的回车和空格。括号内可以注明专门想要去什么。
                        tag=True                              #test.py文件中补充tag的用法
                        continue
                    if tag and read_line.startswith('backend'):    #tag为true且遍历完一个backend段落  #haproxy.conf文件中遍历完一个之后将再次出现backend,因此可以把它作为条件
                            # tag=False    #for循环还会继续,终止不了for循环,不如直接用break 
                            break        #找着了而且遍历完了一个backend块
                    if tag:
                        print('33[1;45m%s33[0m' %read_line,end='')   #end=''用于去掉打印是每行记录后面出现的换行
                        #每找到一个backend块www.oldboy1.org,就将它的信息一条一条地打印出来了,
                        ret.append(read_line)        #加入到ret列表当中,存起来最终作为fetch函数的返回值
            return ret
        elif type == 'change':
            
            with open('haproxy.conf', 'r') as read_f, 
                    open('haproxy.conf_new', 'w') as write_f:    #不能与源文件同名,否则以写的方式打开,原文件直接被清空,还没来得及读
                tag = False                #tag为true相当于遇到需要修改的内容了。
                has_write = False        #
                for read_line in read_f:  
                    if read_line.strip() == backend_data:    #与change函数中拼接内容对比    # 只匹配backend 主机名(所以此句只会匹配成功一次并将tag改为true)                
                        tag = True        #当tag为True之后,只要没读完本backend的内容,就会进入第三个if对应的else当中,
                        continue        #直接进入下一次循环,即下一次开始就再也不会执行此if语句了
                    if tag and read_line.startswith('backend'):    #标识下一个backend则应该关闭tag   # tag为true且遍历完一个backend段落,遇到下一个主机名的backend    
                        tag = False        #不能break
                    
                    if not tag:                            #读一行写一行,没有遇到要求修改的,直接将不改的写入
                        write_f.write(read_line)
                    else:            #读到需要修改的内容了,将新的record写入新文件(这里只写入了所有sever,没有写backend www.oldboy1.com),因为这句话进来时在第一个if中被continue掉了
                        if not has_write:        #如果不加这个,有一个server就会写一遍backend,这样会新增好几条oldboy1的backend记录
                            for record in res:            #把新记录中的所有sever全部写出来
                                write_f.write(record)    #列表中只有sever信息,因为找到时在第一个if中tag=true后就直接continue了
                            has_write = True            #标识已经写完一遍修改后的backend,否则下一个sever进来又会将整个正确的backend块再写一遍
    # 新文件覆盖掉源文件 。改的是文件名,字符串没有任何变化      
            os.rename('haproxy.conf', 'haproxy.conf.bak')        #原来文件改名成后一项名字
            os.rename('haproxy.conf_new', 'haproxy.conf')        #新的文件覆盖到初始文件名对应的文件
            os.remove('haproxy.conf.bak')                        #删除临时文件,haproxy.conf_new依旧存在,可以不用删除
    
    def fetch(data):
        print('33[1;43m这是查询功能33[0m')                #33加颜色
        print('33[1;43m用户数据是33[0m',data)
        backend_data='backend %s' %data
        return file_handler(backend_data)        #调用file handler函数
    
    def add():
        pass
    
    def change(data):            #输入data所以形参也要加上data
        # print('这是修改功能')
        # print('用户输入的数据是',data)  #输入为字典形式:第一个:需要修改哪一个记录;第二个要改成什么样子的记录
        # [{'backend':'www.oldboy1.org','record':{'server':'2.2.2.4','weight':20,'maxconn':3000}},
        #   {'backend':'www.oldboy1.org','record':{'server':'2.2.2.5','weight':30,'maxconn':4000}}]
        backend=data[0]['backend']  #此句只取了一个主机名字
        #提取出输入的想要修改的文件当中的一条记录 www.oldboy1.org   列表的第0编号中字典的‘backend’关键字对应的
        # 用户输入的是字符串记得送入函数之前,即用户一输入data,就应该把data利用eval转化为
        backend_data='backend %s' %backend             #将主机名前面补全成系统文件中格式:   backend www.oldboy1.org
        #       server 2.2.2.4 2.2.2.4 weight 20 maxconn 3000
    
        #列表中每行都有一个换行符
    别忘记了,否则无法匹配
        old_server_record='%sserver %s %s weight %s maxconn %s
    ' %(' '*8,data[0]['record']['server'],    #空格乘以8,表示开头有八个空格
                                                                  data[0]['record']['server'],
                                                                  data[0]['record']['weight'],
                                                                  data[0]['record']['maxconn'])
    
        new_server_record = '%sserver %s %s weight %s maxconn %s
    ' % (' ' * 8, data[1]['record']['server'],
                                                                     data[1]['record']['server'],
                                                                     data[1]['record']['weight'],
                                                                     data[1]['record']['maxconn'])
        print('用户想要修改的记录是',old_server_record)
        res=fetch(backend)             #fetch('www.oldboy1.org')判断你要改的记录在不在文件中。res为backend块除头部的全部内容
        print('来自change函数--》',res)                    #调用fetch函数,返回了res的数值
        if not res or old_server_record not in res:
            return '你要修改的记录不存在'
        else:
            index=res.index(old_server_record)    #取出要修改文件的索引
            res[index]=new_server_record        #在新的列表res中将相应待修改位置的元素放入新的数值
        #注意:列表是可以修改的,但文件只能通过覆盖的方式
    
        res.insert(0,'%s
    ' %backend_data)        #在写入文件之前提前在res中写入待修改的backend行,    用insert加在最前面不要用append
        #从而对应利用backend信息修改tag为true之后直接continue,就不用写入backend www.oldboy1.com语句了
        file_handler(backend_data,res=res,type='change')
    
    def delete():
        pass
        
    # print(_name_)            #__main__    说明如果系统变量_name_的值就是'__main__'。
    #当你把python文件直接当做一个脚本,非模块(一个单独的程序去运行时)有这个等式成立:__name__ = '__main__'
    
    
    #下面是测试代码。一般下python文件只写各种功能便于别人调用
    if __name__ == '__main__':
        msg='''
        1:查询
        2:添加
        3:修改    
        4:删除
        5:退出
        '''
    #对于修改功能:先要检索用户想要修改的记录是否在列表中,如果在才能修改。因此fetch查询功能在别的功能里也会用到。
        msg_dic={            #函数字典,用户输入对应的函数编号,就能通过下方代码匹配到相应的函数密码检测名称,从而调用函数
            '1':fetch,    #此处只写函数名,不加()
            '2':add,
            '3':change,
            '4':delete,
        }
    # 5:可以不写  ‘5’=exit直接用break来在循环中实现
        while True:
            print(msg)
            choice=input('请输入你的选项:').strip()    #去掉数据中的空格和换行符
            if not choice:continue
            if choice == '5':break
    
            data=input('请输入你的数据:').strip()      #选择后进一步的数据操作
    
            if choice != '1':            #2,3,4都非查询,需要修改数据类型
                data=eval(data)    #eval可以提取字符串中的数据运算一遍,或者提取数据结构:''
                #eval不能操作一个字符串,例如‘advduhvih’传入eval中就会报错
    
            res=msg_dic[choice](data)            #根据choice的编号在函数字典中找到对应的函数名,从而调用函数
            # 并把data作为参数放在在括号中,输入给函数
            print('最终结果是--》',res)            #打印出一条条server,backend
    
            
            
    #修改模式下传入的待修改记录:# >>>[{'backend':'www.oldboy1.org','record':{'server':'2.2.2.4','weight':20,'maxconn':3000}},{'backend':'www.oldboy1.org','record':{'server':'2.2.2.5','weight':30,'maxconn':4000}}]

     二、 tag的用法

    # tag的用法
    # 为了能在下一层成功跳转到上一层去用break
    # 如果执行一个quit_all,就能退出所有循环,利用一个状态tag来标识所有所有都是
    tag=True
    while tag:
        print('leve1')
        choice=input("level1>>: ").strip()
        if choice == 'quit':break
        if choice == 'quit_all': tag = False
        while tag:
            print('level2')
            choice = input("level2>>: ").strip()
            if choice == 'quit': break
            if choice == 'quit_all': tag = False
            while tag:
                print('level3')
                choice = input("level3>: ").strip()
                if choice == 'quit': break
                if choice == 'quit_all': tag = False
    
    import os
    # os.rename('a.txt','a.txt.bak')
    os.rename('b.txyt','a.txt')
  • 相关阅读:
    go mod 安装依赖 unkown revision问题解决
    K8S学习笔记
    TCP time_wait close_wait问题(可能是全网最清楚的例子)
    认识beanstalkd
    【线上问题系列】DB字段类型变更导致核心服务不可用
    mysql 类型自动化转换问题
    curl 用法
    requests访问https站点证书告警问题
    博客目录
    工作随笔——elasticsearch数据冷热分离、数据冷备
  • 原文地址:https://www.cnblogs.com/Josie-chen/p/8716329.html
Copyright © 2011-2022 走看看