别再说了。配置所有内容。
configable的Python项目详细描述
安装
pip install configable
示例
fromconfigableimportConfigable,settingclassCar(Configable):fuel_efficiency=setting(required=true,kind=float)units=setting(default='metric',choices=['metric','english'])defmpg(self):eff=self.fuel_efficiencyreturneffifself.units=='english'else2.35214583*effcar=Car({'fuel_efficiency':30,'units':'metric'})printcar.mpg()
教程
可配置
通过子类化configable并添加 settings。 这里有一个非常简单的例子。出于介绍的目的,设置 没有选项;这意味着它们是可选的,并且 值是从任何配置对象实例化的 全班同学。
classAnimal(Configable):species=setting()sound=setting()defspeak(self):printself.sound
configable在其构造函数中需要一个参数:a 配置对象。config对象只是一个普通的旧python 字典,可能是从json/yaml/etc配置文件加载的。它应该 包含与 settings 在它正在实例化的可配置文件上定义。
cheetah=Animal({'species':'acinonyx jubatus','sound':'rawr'})
遗传
当我们对configable的子类进行子类划分时,我们正在做一些 父类的专门化。这通常意味着 对于在父类上定义的一个(或多个)设置,它意味着 专业化。这样的特殊值是使用^{tt1}指定的$ 财产。例如,
classCheetah(Animal):SUBTYPE={'species':'acinonyx jubatus'}defspeak(self):print'rawr'# hard-coded sound
SUBTYPE应该是一个字典,其中的键/值与 父类上定义的设置。^{tt1}的目的$ 属性用于标识匹配的配置对象(传递到 父类构造函数)作为 父类。换句话说,我们将继承方案注入 无继承哈希表数据结构。
举个例子来说就简单多了;指定SUBTYPE属性允许 这种疯狂:
cheetah=Animal({'species':'acinonyx jubatus'})printisinstance(cheetah,Cheetah)//True!cheetah.speak()//'rawr'
动物构造器用于创建一个cheetah实例。
SUBTYPE也可以指定为staticmethod来处理更多 一般条件:
classCheetah(Animal):@staticmethoddefSUBTYPE(config):returnconfig.get('species')=='acinonyx jubatus'defspeak(self):print'rawr'# hard-coded sound
在这种情况下,SUBTYPE函数应该返回true,如果它的类 应该被实例化,而不是这个的父类 配置对象。
现在,您可以在配置文件中包含动物集合:
{"cheetah":{"species":"acinonyx jubatus"},"grizzly":{"species":"ursus arctos","sound":"roar!"}}
并为每个子类实例化正确的子类。说到 哪个…
可配置映射
configablemap只是字符串和configables之间的映射。这个 类非常简单;如果要查看源代码 怎么回事。或者,用这个有趣的例子来说明这一切:
fromconfigableimportConfigable,ConfigableMap,settingclassDog(Configable):breed=setting()classDogs(ConfigableMap):TYPE=Dogdogs=Dogs({'gracie':{'breed':'golden'},'spot':{'breed':'terrier'}})printisinstance(dogs.gracie,Dog)//True!
确保将Type属性分配给 可配置的地图原型!你得到了子类的所有好处 实例化
可配置数组
给定 ConfigableMap, 你应该对一个例子感到满意,
fromconfigableimportConfigable,ConfigableArray,settingclassDog(Configable):breed=setting()classDogs(ConfigableArray):TYPE=Dogdogs=Dogs([{'breed':'golden'},{'breed':'terrier'}])printisinstance(dogs[0],Dog)//True!
设置
调用此函数并将结果分配给可配置的 子类(见上面的许多例子)。一般(如图所示选项 值是默认值),
classType(Configable):setting_name=setting(required=False,# Booleandefault=None,# Instance of expected type (see 'kind' below)choices=None,# List of type expected in config objkind=None# Callable)
此外,还可以使用setting作为装饰器。
classType(Configable):@setting(required=False,# Booleandefault=None,# Instance of expected type (see 'kind' below)choices=None,# List of type expected in config objkind=None# Callable)defsetting_name(self,value):# Do something with value
修饰后的函数将在值 在实例上设置(之后 kind是 调用)。您应该not尝试从内部访问其他设置 函数,因为它们可能尚未加载。如果你需要打电话给 父类修饰函数,必须使用以下语法,
classParent(Configable):@setting()defname(self,value):self.capname=value.upper()classChild(Parent):@setting()defname(self,value):Parent.name(self,value)# MUST USE THIS SYNTAXprintself.capname
以下是设置选项的简要说明。
required {bool}
如果设置为true,则包含可配置子类的实例化将 如果配置对象上的设置未定义,则失败得可怕。
default {*}
不言而喻。你可能想要 required到 如果要提供默认设置值,请使用false。违约 值应为raw值,即 配置对象(基本的,如int、str、dict、list等)。这个 默认值(如果采用)将通过以下所有设置检查运行 还有行动。
choices {iterable<*>}
如果您的设置值被限制在一个小集合内,请在此处列出它们。 如果raw值不在此 准备好了。
kind {callable}
配置对象中的原始值将通过此 函数;因此,它应该接受单个值并返回 转换值或引发错误。这通常被设置为一个类, 尤其是当您需要嵌套的可配置文件时。