python RawConfigParser
python RawConfigParser
我正在使用 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
对象的构造和解构有关?
我在没有 class 的情况下尝试过,然后就没有问题了。
我是 Python 的初学者,所以这可能不是处理此问题的最佳方法。
真正的应用程序是动态的,因为 ini 文件的数量和位置在应用程序的使用过程中会发生变化。 ini文件列表是用os.listdir(folder)
构建的
您造成的困惑是像这样定义 ConfigParser:
class status_file:
myConfig = ConfigParser.RawConfigParser()
myConfig.optionxform = str
def __init__(self, str_statusfile):
...
使 myConfig
属性成为 status_file
的 class 属性,这与 Java 不同。
因此,当您解析第二个文件时,相同的配置将解析它,并将其选项与它解析的第一个文件合并。
为避免您的问题,只需在 __init__
方法内将解析器创建为实例属性:
class status_file(object):
def __init__(self, str_statusfile):
self.myConfig = ConfigParser.RawConfigParser()
self.myConfig.optionxform = str
...
附带说明一下,如果您使用的是 Python 版本 2.x,您的 class 应该继承自 object
。否则,您将使用旧式 (pre-python2.2) classes,它们可能会给您带来许多微妙的问题。
这是初学者常见的 python 错误。我假设您了解 Java 或 C++ 之类的语言,不是吗?
在您的 class 中 myConfig
是 class 的属性,而不是它的实例。默认 Python 行为是首先查看实例属性,然后查看 class 属性,因此 self.myConfig
在两个实例中是完全相同的解析器。有关详细信息,请参阅 this。
您的解决方案是在构造函数 (__init__
) 中创建和配置解析器,而不是 class 声明。
这可能会帮助您理解为什么 myConfig 是 class 属性,而不是实例属性:
当你这样写的时候:
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
如果您需要动态创建新的 class,这可能会派上用场。
由于 A
是 class,它的 __call__
方法最终导致调用它的 __new__
和 __init__
方法,这将导致创建新实例,这将共享相同的对象 A
和它的 __class__
属性(这是简化,它不是内部发生的全部,但对于一般 Pythoning 来说就足够了 ;)).
我正在使用 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
对象的构造和解构有关?
我在没有 class 的情况下尝试过,然后就没有问题了。
我是 Python 的初学者,所以这可能不是处理此问题的最佳方法。
真正的应用程序是动态的,因为 ini 文件的数量和位置在应用程序的使用过程中会发生变化。 ini文件列表是用os.listdir(folder)
您造成的困惑是像这样定义 ConfigParser:
class status_file:
myConfig = ConfigParser.RawConfigParser()
myConfig.optionxform = str
def __init__(self, str_statusfile):
...
使 myConfig
属性成为 status_file
的 class 属性,这与 Java 不同。
因此,当您解析第二个文件时,相同的配置将解析它,并将其选项与它解析的第一个文件合并。
为避免您的问题,只需在 __init__
方法内将解析器创建为实例属性:
class status_file(object):
def __init__(self, str_statusfile):
self.myConfig = ConfigParser.RawConfigParser()
self.myConfig.optionxform = str
...
附带说明一下,如果您使用的是 Python 版本 2.x,您的 class 应该继承自 object
。否则,您将使用旧式 (pre-python2.2) classes,它们可能会给您带来许多微妙的问题。
这是初学者常见的 python 错误。我假设您了解 Java 或 C++ 之类的语言,不是吗?
在您的 class 中 myConfig
是 class 的属性,而不是它的实例。默认 Python 行为是首先查看实例属性,然后查看 class 属性,因此 self.myConfig
在两个实例中是完全相同的解析器。有关详细信息,请参阅 this。
您的解决方案是在构造函数 (__init__
) 中创建和配置解析器,而不是 class 声明。
这可能会帮助您理解为什么 myConfig 是 class 属性,而不是实例属性: 当你这样写的时候:
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
如果您需要动态创建新的 class,这可能会派上用场。
由于 A
是 class,它的 __call__
方法最终导致调用它的 __new__
和 __init__
方法,这将导致创建新实例,这将共享相同的对象 A
和它的 __class__
属性(这是简化,它不是内部发生的全部,但对于一般 Pythoning 来说就足够了 ;)).