Python 使用ConfigParser创建包含文件中指定的所有元素的类
我已经创建了一个类似于.ini的文件,其中包含我以后在程序中需要的所有值,请参见以下内容:Python 使用ConfigParser创建包含文件中指定的所有元素的类,python,python-2.7,configparser,Python,Python 2.7,Configparser,我已经创建了一个类似于.ini的文件,其中包含我以后在程序中需要的所有值,请参见以下内容: [debugging] checkForAbort = 10 ... [official] checkForAbort = 30 ... 我希望将所有这些项读入一个类中,并使其可以从python项目的其他部分访问。 到目前为止,我掌握的代码如下: from ConfigParser import SafeConfigParser import glob class ConfigurationPara
[debugging]
checkForAbort = 10
...
[official]
checkForAbort = 30
...
我希望将所有这些项读入一个类中,并使其可以从python项目的其他部分访问。
到目前为止,我掌握的代码如下:
from ConfigParser import SafeConfigParser
import glob
class ConfigurationParameters
def __init__(self):
self.checkForAbortDuringIdleTime = None
parser = SafeConfigParser()
# making a list here in case we have multiple files in the future!
candidatesConfiguration = ['my.cfg']
foundCandidates = parser.read(candidatesConfiguration)
missingCandidates = set(candidatesConfiguration) - set(found)
if foundCandidates:
print 'Found config files:', sorted(found)
else
print 'Missing files :', sorted(missing)
print "aborting..."
# check for mandatory sections below
for candidateSections in ['official', 'debugging']:
if not parser.has_section(candidateSections)
print "the mandatory section", candidateSections " is missing"
print "aborting..."
for sectionName in ['official', 'debugging']:
for name, value in parser.items(section_name):
self.name = value
我是python新手,但我仍然可以看到我的代码存在很多问题:
- 我被迫为类文件中的每个项添加属性。并使配置文件和我的类始终保持同步
- 这个类不是一个单例类,因此读取/解析将从导入它的任何地方进行李>
- 如果在我的类中没有定义的配置文件中添加值,它可能会崩溃李>
我的类只需要读取值,因此不需要写入配置文件
self.name=value
无法按预期工作。您的意思可能是setattr(self、name、value)
它动态地创建实例属性
要使其成为单例,可以在config
/settings
模块中将实例设置为全局变量。在程序启动时初始化它一次,例如,像日志记录
模块为根日志记录程序执行的那样:logging.config.fileConfig('logging.conf')
对于本质上是一个dict(例如,argparse.Namespace
,带有命令行选项)的对象,通常希望使用属性访问
您可以稍后通过导入来访问配置:从mypackage.config导入配置
,例如,mypackage/config.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
在mypackage/\uuuuu main\uuuuuuu.py
中:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
注意:setattr()
即使设置了属性也能正常工作<代码>\uuuu dict\uuuuu.update()在这种情况下中断:
class XValidatorMixin(object):
@property
def x(self):
return self._x
@x.setter
def x(self, value):
if value < 0:
raise ValueError
self._x = value
class CUpdate(XValidatorMixin):
def __init__(self, **options):
self.__dict__.update(options)
class CSetAttr(XValidatorMixin):
def __init__(self, **options):
for name, value in options.items():
setattr(self, name, value)
for C in [CUpdate, CSetAttr]:
o = C(a=1, b=2) # non-property attributes work as expected
assert o.a == 1 and o.b == 2
o = CSetAttr(x=1)
assert o.x == 1 # setattr also sets property
o = CUpdate(x=1)
try:
o.x # .update() doesn't set property
except AttributeError:
pass
else:
assert 0
try:
o = CSetAttr(x=-1) # invokes property setter
except ValueError: # that correctly reject negative values
pass
else:
assert 0
类XValidatorMixin(对象):
@财产
def x(自我):
返回自我
@x、 塞特
def x(自身,值):
如果值<0:
升值误差
self._x=值
类别CUpdate(Xin):
定义初始化(自我,**选项):
自我记录更新(选项)
CSetAttr类(XIN):
定义初始化(自我,**选项):
选项.items()中的值作为名称:
setattr(自身、名称、值)
对于[CUpdate,CseAttr]中的C:
o=C(a=1,b=2)#非属性属性按预期工作
断言o.a==1和o.b==2
o=Csettr(x=1)
assert o.x==1#setattr还设置属性
o=截止日期(x=1)
尝试:
o、 x#.update()未设置属性
除属性错误外:
通过
其他:
断言0
尝试:
o=CSetAttr(x=-1)#调用属性setter
ValueError除外:#正确拒绝负值
通过
其他:
断言0
self.name=value
无法按预期工作。您的意思可能是setattr(self、name、value)
它动态地创建实例属性
要使其成为单例,可以在config
/settings
模块中将实例设置为全局变量。在程序启动时初始化它一次,例如,像日志记录
模块为根日志记录程序执行的那样:logging.config.fileConfig('logging.conf')
对于本质上是一个dict(例如,argparse.Namespace
,带有命令行选项)的对象,通常希望使用属性访问
您可以稍后通过导入来访问配置:从mypackage.config导入配置
,例如,mypackage/config.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
在mypackage/\uuuuu main\uuuuuuu.py
中:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
注意:setattr()
即使设置了属性也能正常工作<代码>\uuuu dict\uuuuu.update()在这种情况下中断:
class XValidatorMixin(object):
@property
def x(self):
return self._x
@x.setter
def x(self, value):
if value < 0:
raise ValueError
self._x = value
class CUpdate(XValidatorMixin):
def __init__(self, **options):
self.__dict__.update(options)
class CSetAttr(XValidatorMixin):
def __init__(self, **options):
for name, value in options.items():
setattr(self, name, value)
for C in [CUpdate, CSetAttr]:
o = C(a=1, b=2) # non-property attributes work as expected
assert o.a == 1 and o.b == 2
o = CSetAttr(x=1)
assert o.x == 1 # setattr also sets property
o = CUpdate(x=1)
try:
o.x # .update() doesn't set property
except AttributeError:
pass
else:
assert 0
try:
o = CSetAttr(x=-1) # invokes property setter
except ValueError: # that correctly reject negative values
pass
else:
assert 0
类XValidatorMixin(对象):
@财产
def x(自我):
返回自我
@x、 塞特
def x(自身,值):
如果值<0:
升值误差
self._x=值
类别CUpdate(Xin):
定义初始化(自我,**选项):
自我记录更新(选项)
CSetAttr类(XIN):
定义初始化(自我,**选项):
选项.items()中的值作为名称:
setattr(自身、名称、值)
对于[CUpdate,CseAttr]中的C:
o=C(a=1,b=2)#非属性属性按预期工作
断言o.a==1和o.b==2
o=Csettr(x=1)
assert o.x==1#setattr还设置属性
o=截止日期(x=1)
尝试:
o、 x#.update()未设置属性
除属性错误外:
通过
其他:
断言0
尝试:
o=CSetAttr(x=-1)#调用属性setter
ValueError除外:#正确拒绝负值
通过
其他:
断言0
此外,您还可以这样做:
文件MyConfig.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
文件MyProgram.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
声明“Import语句分两步执行:(1)查找模块,必要时对其进行初始化;(2)在本地名称空间(Import语句发生的范围)中定义一个或多个名称。”
这意味着,当一个模块被导入时,一个或多个本地名称被绑定到一个模块对象,并且只有在Python程序运行时第一次导入它时,它才会被初始化(即从文件读取并运行)
在上面的代码中,名称config
只是引用模块对象属性的本地名称。Python解释器在MyProgram
中引用模块对象时(通过MyConfig导入配置中的初始化)。当MyProgram
导入foo
时,它已经初始化并绑定到模块foo
和MyProgram
中的本地名称,我们可以将其称为foo.config
。但这两个名称都指同一个对象。
此外,您还可以这样做:
文件MyConfig.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
文件MyProgram.py
:
class Config(object):
...
config = Config() # empty or default config without any configuration
from .config import config
...
# initialization code
config.update_from_file('mypackage.conf') # it might call `setattr()` inside
from ConfigParser import SafeConfigParser
section_names = 'official', 'debugging'
class MyConfiguration(object):
def __init__(self, *file_names):
parser = SafeConfigParser()
parser.optionxform = str # make option names case sensitive
found = parser.read(file_names)
if not found:
raise ValueError('No config file found!')
for name in section_names:
self.__dict__.update(parser.items(name)) # <-- here the magic happens
config = MyConfiguration('my.cfg', 'other.cfg')
from MyConfig import config
# ...
from MyConfig import config
print config.checkForAbort
import foo
assert config is foo.config
“导入语句”的状态为e