提交 e3645fb5 authored 作者: James Bergstra's avatar James Bergstra

configparser - second draft w more documentation and fewer bugs

上级 d4410359
...@@ -85,51 +85,83 @@ def fetch_val_for_key(key): ...@@ -85,51 +85,83 @@ def fetch_val_for_key(key):
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
raise KeyError(key) raise KeyError(key)
_config_var_list = []
def _config_print(thing, buf):
for cv in _config_var_list:
print >> buf, cv
print >> buf, " Doc: ", cv.doc
print >> buf, " Value: ", cv.val
print >> buf, ""
class TheanoConfigParser(object): class TheanoConfigParser(object):
#properties are installed by AddConfigVar #properties are installed by AddConfigVar
_i_am_a_config_class = True
def __str__(self): def __str__(self):
sio = StringIO.StringIO() sio = StringIO.StringIO()
_config_print(self.__class__, sio) _config_print(self.__class__, sio)
return sio.getvalue() return sio.getvalue()
pass
# N.B. all instances of TheanoConfigParser give access to the same properties. # N.B. all instances of TheanoConfigParser give access to the same properties.
config = TheanoConfigParser() config = TheanoConfigParser()
_config_var_list = [] #
# The data structure at work here is a tree of CLASSES with CLASS ATTRIBUTES/PROPERTIES that
def _config_print(thing, buf): # are either a) INSTANTIATED dynamically-generated CLASSES, or b) ConfigParam instances.
for cv in _config_var_list: # The root of this tree is the TheanoConfigParser CLASS, and the internal nodes are the SubObj
print >> buf, cv # classes created inside of AddConfigVar().
print >> buf, " Doc: ", cv.doc # Why this design ?
print >> buf, " Value: ", cv.val # - The config object is a true singleton. Every instance of TheanoConfigParser is an empty
print >> buf, "" # instance that looks up attributes/properties in the [single] TheanoConfigParser.__dict__
# - The subtrees provide the same interface as the root
# - ConfigParser subclasses control get/set of config properties to guard against craziness.
def AddConfigVar(name, doc, configparam, root=config):
"""Add a new variable to theano.config
:type name: string for form "[section0.[section1.[etc]]].option"
:param name: the full name for this configuration variable.
:type doc: string
:param doc: What does this variable specify?
:type configparam: ConfigParam instance
:param configparam: an object for getting and setting this configuration parameter
:type root: object
:param root: used for recusive calls -- don't provide an argument for this parameter.
:returns: None
"""
# this method also performs some of the work of initializing ConfigParam instances
def AddConfigVar(name, doc, thing, cls=TheanoConfigParser): if root is config:
if cls == TheanoConfigParser: #only set the name in the first call, not the recursive ones
thing.fullname = name configparam.fullname = name
if hasattr(TheanoConfigParser, name): sections = name.split('.')
raise ValueError('This name is already taken') if len(sections) > 1:
parts = name.split('.')
if len(parts) > 1:
# set up a subobject # set up a subobject
if not hasattr(cls, parts[0]): if not hasattr(root, sections[0]):
# every internal node in the config tree is an instance of its own unique class
class SubObj(object): class SubObj(object):
pass _i_am_a_config_class = True
setattr(cls, parts[0], SubObj) setattr(root.__class__, sections[0], SubObj())
AddConfigVar('.'.join(parts[1:]), doc, thing, cls=getattr(cls, parts[0])) newroot = getattr(root, sections[0])
if not getattr(newroot, '_i_am_a_config_class', False) or isinstance(newroot, type):
raise TypeError('Internal config nodes must be config class instances', newroot)
return AddConfigVar('.'.join(sections[1:]), doc, configparam, root=newroot)
else: else:
thing.doc = doc if hasattr(root, name):
thing.__get__() # trigger a read of the value raise AttributeError('This name is already taken', configparam.fullname)
setattr(cls, parts[0], thing) configparam.doc = doc
_config_var_list.append(thing) configparam.__get__() # trigger a read of the value from config files and env vars
setattr(root.__class__, sections[0], configparam)
_config_var_list.append(configparam)
class ConfigParam(object): class ConfigParam(object):
def __init__(self, default, filter=None): def __init__(self, default, filter=None):
self.default = default self.default = default
self.filter=filter self.filter=filter
# there is a name attribute too, but it is set by AddConfigVar # N.B. --
# self.fullname # set by AddConfigVar
# self.doc # set by AddConfigVar
def __get__(self, *args): def __get__(self, *args):
#print "GETTING PARAM", self.fullname, self, args #print "GETTING PARAM", self.fullname, self, args
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论