zoukankan      html  css  js  c++  java
  • Python

    configParser 模块用于操作配置文件

    注:Parser汉译为“解析”之意。

    配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。

    为了更好的理解本文,我们先了解一下配置文件的组成及命名:配置文件(INI文件)由章节(section [sectionName] )、键、值组成(key=value or key:Value)。

    # 新建一个config 文件 testconfig.ini
    
    [DATABASE]
    host = 50.23.190.57
    username : TestYang
    password = TestYang
    port = 3306
    database = TestDB

    具体用法见一下代码,写的很详细了。

    #-*-coding:utf-8-*-
    # Time:2017/10/18 22:30
    # Author:YangYangJun
    
    # 首先导入 ConfigParser 模块
    
    import ConfigParser
    
    # 这里发现 上面这种大写与下面的小写都可以,只是导入的时候是如何写的,下面实例化的时候就如何写。
    
    # import configparser
    
    configFile = 'testconfig.ini'
    
    
    # 1、创建ConfigParser 实例
    
    config = ConfigParser.ConfigParser()
    
    # 2、读取配置文件
    
    config.read(configFile)
    
    # 3、获取配置文件的章节序列
    
    print config.sections()  # ['DATABASE']
    
    
    # 4、获取配置文件中对应章节所有键的序列
    
    print config.options('DATABASE')  # ['host', 'username', 'password', 'port', 'database']
    
    # 5、获取配置文件中对应章节 对应键的值
    
    print config.get('DATABASE','host') # 50.23.190.57
    
    
    # 6、获取配置文件中对应章节的所有键值对
    
    print config.items('DATABASE')  # [('host', '50.23.190.57'), ('username', 'TestYang'), ('password', 'TestYang'), ('port', '3306'), ('database', 'TestDB')]
    
    
    
    # 7、往配置文件中增加章节section
    
    # 重新实例化一个对象,如果使用上面已经read的对象的话,write的时候会将已经读的内容再写一遍。
    writeConfig = ConfigParser.ConfigParser()
    
    # 8、增加章节section
    writeConfig.add_section("UserInfo")
    
    # 9、set 往配置文件中的[UserInfo]节点加入键值对
    
    writeConfig.set("UserInfo",'username','TestYang')
    
    writeConfig.set("UserInfo",'password','TestYangPassWord')
    
    writeConfig.set("UserInfo",'age','18')
    
    writeConfig.set("UserInfo",'country','China')
    
    # 10、已追加的方式打开已经存在的文件,如果文件不存在则创建该文件
    
    # writeConfig.write(open('testconfig.ini','a'))
    
    # 上面的写入代码等价于下面的代码
    '''
    f = open('testconfig.ini','a')
    writeConfig.write(f)
    '''
    
    # 注意 如果 分开先写  writeConfig.add_section("UserInfo") 然后在单独执行set 会报如下错误
    # 所以 add_section 和 set 要一起写,一起执行
    '''
      raise NoSectionError(section)
    ConfigParser.NoSectionError: No section: 'UserInfo'
    '''
    # 写入后的结果如下
    '''
    [UserInfo]
    username = TestYang
    password = TestYangPassWord
    age = 18
    country = China
    '''
    
    
    # 11、按照类型读取指定section 的option 信息 有getint 同样的还有getfloat、getboolean。
    
    # 返回为string类型
    print config.get("UserInfo",'age')
    # 返回为int类型
    print config.getint("UserInfo",'age')
    
    # 12、移除option
    
    config.remove_option('UserInfo','age')
    
    # 13、 移除section, 移除节点后,节点下的键值对一起移除
    config.remove_section('UserInfo')
    
    # 只要有修改就要写回文件保存
    config.write(open("testconfig.ini", "w"))
    
    # 其他格式的配置文件
    # cf.write(open("test.conf", "w"))

    执行后结果如下:

    # 新建一个config 文件 testconfig.ini
    
    [DATABASE]
    host = 50.23.190.57
    username : TestYang
    password = TestYang
    port = 3306
    database = TestDB
    
    
    
    [UserInfo]
    username = TestYang
    password = TestYangPassWord
    age = 18
    country = China

    应用实例如下:

    # 应用实例,可以新建一个py文件,将使用的方法封装起来
    
    class ReadConfig():
        def __init__(self):
    
            self.cf = ConfigParser.ConfigParser()
            self.cf.read(configFile)
    
        def get_UserInfo(self, username):
            value = self.cf.get("UserInfo", username)
            return value
    
        def get_http(self, name):
            value = self.cf.get("HTTP", name)
            return value
    
        def get_db(self, name):
            value = self.cf.get("DATABASE", name)
            return value
    
    
    if __name__ == "__main__":
        getdata = ReadConfig()
        print  getdata.get_UserInfo("username") # TestYang
        print  getdata.get_db("database")  # TestDB

    使用过程遇到问题

    1、configparser读取含有中文配置config.ini(Windows)显示乱码的解决方法

    2、UnicodeDecodeError: 'gbk' codec can't decode bytes in position 243-244: illegal multibyte sequence

     以上问题处理方法:在read 方法中加入参数  encoding="utf-8-sig" 即可,支持python3

            self.cf = configparser.ConfigParser()
            # 处理配置文件中含中文字符的问题 ,UnicodeDecodeError: 'gbk' codec can't decode bytes in position 243-244: illegal multibyte sequence
    
            self.cf.read(configPath,encoding="utf-8-sig")

    3、遇到的这个问题真是个坑,坑了我一天,最后终于通过对比打印内容输出,发现了问题的关键。

    [EMAIL]
    Smtp_Server1 = 'smtp.mxhichina.com'
    Smtp_Server2 = smtp.mxhichina.com

    其实configparser 读取配置文件的内容是原样输出的。

    即读取 Smtp_Server1  读取的内容就是  'smtp.mxhichina.com', 而不是实际需要的 smtp.mxhichina.com

    这里不像py文件中的 'smtp.mxhichina.com',py会将其处理为字符串,单作为参数时是 smtp.mxhichina.com

    所以py文件可以这样写。

    Smtp_Server = 'smtp.mxhichina.com'

    4、关于smtplib发送测试报告遇到的问题。

    发送邮件部分代码

    tmp = smtp.sendmail(sender, receiver, msg.as_string())
    #正常邮件参数值如下
    Smtp_Sender = 'dev@we.cn'
    Smtp_Sender_Password = '322118'
    Smtp_Receiver = ['ywert@we.cn','qwer@we.cn']

    并且configparser是原样读取的

    所以我就这样写了

    Pre_Receiver = ['qwer@we.cn']

    结果会提示发送失败

    {u"['wer@we.cn']": (500, 'Error: bad syntax')}
    发送失败!

    然后尝试着去掉列表符号以及引号尝试一下。

    Test_Receiver = qwer@we.cn

    结果提示发送成功,并实际收到了邮件

    但是结果如图

    这样的结果还是有问题的,考虑到receiver 本就应该是列表结构的,所以后面再做一下处理

    receiver = []
    receiver.append(self.TReceiver)

    这样后邮件就显示正常了。

    整理后代码如下

          receiver = []
                receiver.append(self.TReceiver)
                print receiver
                # 定义发件人,如果不写,发件人为空
                self.msg['From'] = self.sender
                # 定义收件人,如果不写,收件人为空,后发现其实msg['To'] = “,”.join(receiver) 这里是必须序列化的参数,不过不这样就会出现上图的问题,而其下面的那条语句其实不处理也能发送出去。

    self.msg['To'] = ",".join(receiver)
                self.smtp.sendmail(self.sender, receiver, self.msg.as_string())

    但是还有一个问题,那就收件人有多个情况如何处理了。

    # 比如
    receiver = 123456@qq.com/1254367@qq.com

    处理代码如下

    self.receiver = []
            for n in str(self.value).split("/"):
                self.receiver.append(n)

    “/” 是分隔符,可以根据 receiver  采用的分割而定。

  • 相关阅读:
    拉格朗日插值
    [数论] hdu 5974 A Simple Math Problem (数论gcd)
    混合图欧拉回路
    上下界网络流
    HDU 6623 Minimal Power of Prime(数学)
    图的连通度
    最小点权覆盖和最大点权独立集
    最大权闭合子图(最小割,蕴含式最大获利问题)
    CodeForces Goodbye 2017
    网络流建模汇总
  • 原文地址:https://www.cnblogs.com/BlueSkyyj/p/7683820.html
Copyright © 2011-2022 走看看