flagpole是一个flag-arg解析器,用于构建具有可选键的字典。
flagpole的Python项目详细描述
旗杆
标记arg parser以生成具有可选键的字典。
安装:
pip install flagpole
用法:
flagpole在cloudaux中用于允许cloudaux用户指定库如何构建项。
旗杆有两类:Flags
和FlagRegistry
。
标志
fromflagpoleimportFlagsFLAGS=Flags('BASE','LISTENERS','RULES')print(FLAGS)# OrderedDict([('BASE', 1), ('LISTENERS', 2), ('RULES', 4), ('ALL', 7), ('None', 0), ('NONE', 0)])print("{0:b}".format(FLAGS.None).zfill(3))# 000print("{0:b}".format(FLAGS.ALL).zfill(3))# 111print("{0:b}".format(FLAGS.BASE).zfill(3))# 001print("{0:b}".format(FLAGS.LISTENERS).zfill(3))# 010print("{0:b}".format(FLAGS.RULES).zfill(3))# 100# combine multiple flags (100 & 010 = 110):print("{0:b}".format(FLAGS.RULES|FLAGS.LISTENERS).zfill(3))# 110
FLAGS.ALL
和FLAGS.None
自动添加。所有其他的都必须添加到构造函数中。
注意:由于我们发现大小写是一个常见的用户错误,因此提供了NONE
和None
。
标志注册表
注册表有两部分:
- 装饰者
@registry.register(...)
- 构建方法
registry.build_out(...)
FlagRegistry专门用于构建具有任意数量可选字段的数据结构(Python字典)。
标记注册表装饰符:
decorator用于包装方法,以指示哪个flag将导致调用该方法,是否有任何其他标志是dependency,以及返回值应放在哪个key下。
支持用多个返回值包装方法。每个返回值可以有一个单独的标志和一个单独的键。
decorator具有以下关键字参数:
- flag:只有使用与此处提供的标志匹配的标志调用
build_out
时,才会调用包装方法。- 可以是标志(如
FLAG.RULES
),或者对于多个返回值,可以是列表或元组。有关示例,请参见source。
- 可以是标志(如
- key:包装函数的返回值将使用提供的键追加到结果字典中。此关键字参数是可选的。如果未提供,则返回值将与结果字典合并(
dict.update(other_dict)
)。- 可以是字符串,或者对于多个返回值,可以是列表或元组。有关示例,请参见source。
- 依赖于:如果在执行另一个包装方法之前不能调用包装方法,则必须在此处放置另一个方法的标志。此关键字参数是可选的。如果提供,则此函数所依赖的函数的结果应作为参数传递给此函数。
标记注册表生成:
registry.build_out(...)
方法接受以下参数:
- flags:用户提供的标志组合。(即
flags = FLAGS.CORS | FLAGS.WEBSITE
) - pass_datastructure:要将结果字典作为参数传递给每个修饰的方法,请将其设置为true。否则,只有在检测到依赖项时才会发送。
- start_with:您可以传入一个字典,以便生成变异。默认情况下,build_out将创建一个新字典并返回它。
- *参数:传递给在flagRegistry中注册的方法
- **kwargs:传递给在flagRegistry中注册的方法
- 返回结果:通过组合所有已执行方法的输出而创建的字典。
build_out
方法执行具有与传递到build_out
的标志匹配的所有注册表修饰方法。
它将遵循任何依赖链以正确的顺序执行方法。
Flags
加上递归跟踪依赖链的能力,在很大程度上是这个包的优点。此包还将检测修饰方法中的任何循环depenency,并引发适当的异常。
完整示例:
fromflagpoleimportFlagRegistry,Flagsfromcloudaux.aws.elbv2importdescribe_listenersfromcloudaux.aws.elbv2importdescribe_rulesregistry=FlagRegistry()FLAGS=Flags('BASE','LISTENERS','RULES')@registry.register(flag=FLAGS.LISTENERS,key='listeners')defget_listeners(alb,**conn):returndescribe_listeners(load_balancer_arn=alb['Arn'],**conn)@registry.register(flag=FLAGS.RULES,depends_on=FLAGS.LISTENERS,key='rules')defget_rules(alb,**conn):rules=list()forlistenerinalb['listeners']:rules.append(describe_rules(listener_arn=listener['ListenerArn'],**conn))returnrules# key is not specified here, so the return value is merged (`dict.update(other_dict)`) with the result dictionary.@registry.register(flag=FLAGS.BASE)defget_base(alb,**conn):return{'region':conn.get('region'),'_version':1}
然后您可以像这样调用registry.build_out()
:
defget_elbv2(alb_arn,flags=FLAGS.ALL,**conn):alb=dict(Arn=alb_arn)registry.build_out(flags,start_with=alb,pass_datastructure=True,**conn)returnresult
注意:您可以构建任意的标志组合,例如:flags=FLAGS.RULES | FLAGS.LISTENERS
对于这个例子,当使用FLAGS.ALL
调用时,结果将是结构如下的词典:
{
'Arn': ...,
'region': ...,
'listeners': ['ListenerArn': ...],
'rules': [...],
'_version': ...,
}
FlagRegistry class完全记录了它的使用。