【问题标题】:python RawConfigParserpython RawConfigParser
【发布时间】:2015-01-29 15:24:25
【问题描述】:

我正在使用RawConfigParser 来读取和更新一个ini 样式的配置文件。这在标准配置中完全没有问题。 我的问题是我在同一个脚本中读取不同的配置文件。无需过多介绍,当我读取第二个配置文件时,它的值将与第一个 ini 文件合并。

两个ini文件的原始内容

infile_1.ini
[section]
option = Original value
extraoption = not in ini file 2

inifile_2.ini
[section]
option = Original value

这是我用来更改 ini 文件内容的代码。重现问题的一小段代码

import ConfigParser

class status_file:
   myConfig = ConfigParser.RawConfigParser()
   myConfig.optionxform = str

   def __init__(self, str_statusfile):
      self.myConfig.read( str_statusfile)
      self.statusfile = str_statusfile

   def option(self, new_value):
      self.myConfig.set("section","option",new_value)
      with open( self.statusfile, "w") as ini_out:
            self.myConfig.write( ini_out )


statusfiles = ['inifile_1.ini', 'inifile_2.ini']
for myStatus in statusfiles:
   myConfig = status_file(myStatus)
   myConfig.option("Something new")

执行此代码后,ini 文件的内容已根据需要更改。但在第二个 ini 文件中,第一个 ini 文件中的选项被合并了。

infile_1.ini
[section]
option = Something New
extraoption = not in ini file 2

inifile_2.ini
[section]
option = Something New
extraoption = not in ini file 2

有什么方法可以重置ConfigParser 内容或其他解决方案吗? 我猜它与ConfigParser 对象的构造和解构有关? 我在没有上课的情况下尝试过,然后就没有问题了。 我是 Python 的初学者,所以这可能不是处理这个问题的最佳方法。 真正的应用程序是动态的,因为在应用程序的使用过程中,ini 文件的数量和位置会发生变化。 ini文件列表是用os.listdir(folder)构建的

【问题讨论】:

    标签: python class configuration-files configparser


    【解决方案1】:

    您造成的困惑是像这样定义 ConfigParser:

    class status_file:
       myConfig = ConfigParser.RawConfigParser()
       myConfig.optionxform = str
    
       def __init__(self, str_statusfile):
           ...
    

    使myConfig 属性成为status_file 属性,这与Java 不同。 因此,当您解析第二个文件时,相同的配置将解析它,并将其选项与它解析的第一个文件合并。

    为避免您的问题,只需将解析器创建为实例属性,在 __init__ 方法内:

    class status_file(object):
    
       def __init__(self, str_statusfile):
           self.myConfig = ConfigParser.RawConfigParser()
           self.myConfig.optionxform = str
           ...
    

    附带说明,如果您使用的是 Python 2.x 版,您的类应该继承自 object。否则,您将拥有旧式(python2.2 之前的)类,这些类可能会给您带来很多微妙的问题。

    【讨论】:

    • 嗯...我们几乎在同一时间发布了几乎相同的内容:P 另外,我忘记提及旧/新样式类问题,所以你得到了我的支持。
    • 谢谢大家,这给了我解决方案和更多见解。像这样更改了我的代码,并像魅力一样工作。
    【解决方案2】:

    这是初学者常见的python错误。我假设您了解 Java 或 C++ 之类的语言,不是吗?

    在你的类中myConfig 是类的属性,而不是实例。默认的 Python 行为是首先查看实例属性,然后查看类属性,因此 self.myConfig 在两个实例中都是完全相同的解析器。有关详细信息,请参阅this

    您的解决方案是在构造函数 (__init__) 中创建和配置解析器,而不是类声明。

    这可以帮助您理解为什么 myConfig 是类属性,而不是实例属性: 当你写这样的东西时:

    class A(B, C):
        def foo(x):
            return 2*x
    

    这只是语法糖:

    def foo(x):
        return 2*x
    A = type("A", (B, C), {"foo": foo})
    del foo
    

    如果您需要动态创建新类,这可能会派上用场。 由于A 是类,它的__call__ 方法最终导致调用它的__new____init__ 方法,这将导致创建新实例,该实例将共享相同的对象A,因为它是__class__ 属性(这是简化,并不是所有的事情都发生在里面,但对于一般的 Pythoning 来说就足够了;))。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-11
      • 2010-11-24
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多