- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想从数据库加载参数和选项。我允许用户定义自己的选项和参数。用户可以通过命令行调用远程api。它们指定端点的 URL 和参数。这是数据库中的数据的样子
[
{
"name": "thename1",
"short": "a",
"long": "ace"
"type": "string",
"required": false
},
{
"name": "thename2",
"short": "b",
"long": "bravo"
"type": "number",
"required": true
},
{
"name": "thename3",
"short": "c",
"long": "candy"
"type": "array",
"required": true
}
]
这些参数与远程端点的需求一致。每个 API 端点都有不同的参数,因此它们需要是动态的。这是命令行的外观。
command run www.mysite.com/api/get -a testparam --bravo testpara2 -c item1 item2
参数和值将映射到 URL 中。有没有办法在点击中设置动态参数?
最佳答案
这可以通过构建一个自定义装饰器来完成,该装饰器在将给定的数据结构转换为点击等效项后多次调用 click.option
装饰器。
import click
def options_from_db(options):
map_to_types = dict(
array=str,
number=float,
string=str,
)
def decorator(f):
for opt_params in reversed(options):
param_decls = (
'-' + opt_params['short'],
'--' + opt_params['long'],
opt_params['name'])
attrs = dict(
required=opt_params['required'],
type=map_to_types.get(
opt_params['type'], opt_params['type'])
)
if opt_params['type'] == 'array':
attrs['cls'] = OptionEatAll
attrs['nargs'] = -1
click.option(*param_decls, **attrs)(f)
return f
return decorator
options_from_db
装饰器:要使用新的装饰器,请装饰命令,并从数据库传递选项数据,如下所示:
@options_from_db(run_options)
def command(*args, **kwargs):
....
与所有装饰器一样,@click.option()
装饰器是一个函数。在这种情况下,它注释了修饰函数,并返回相同的函数。因此我们可以简单地多次调用它来注释我们的装饰函数。
注意:您的 array
参数违反了点击要求,不允许选项上出现 nargs
< 0。但有another answer实现这一点,这个答案使用 the code从那里开始。
class OptionEatAll(click.Option):
def __init__(self, *args, **kwargs):
self.save_other_options = kwargs.pop('save_other_options', True)
nargs = kwargs.pop('nargs', -1)
assert nargs == -1, 'nargs, if set, must be -1 not {}'.format(nargs)
super(OptionEatAll, self).__init__(*args, **kwargs)
self._previous_parser_process = None
self._eat_all_parser = None
def add_to_parser(self, parser, ctx):
def parser_process(value, state):
# method to hook to the parser.process
done = False
value = [value]
if self.save_other_options:
# grab everything up to the next option
while state.rargs and not done:
for prefix in self._eat_all_parser.prefixes:
if state.rargs[0].startswith(prefix):
done = True
if not done:
value.append(state.rargs.pop(0))
else:
# grab everything remaining
value += state.rargs
state.rargs[:] = []
value = tuple(value)
# call the actual process
self._previous_parser_process(value, state)
retval = super(OptionEatAll, self).add_to_parser(parser, ctx)
for name in self.opts:
our_parser = parser._long_opt.get(
name) or parser._short_opt.get(name)
if our_parser:
self._eat_all_parser = our_parser
self._previous_parser_process = our_parser.process
our_parser.process = parser_process
break
return retval
run_options = [
{
"name": "thename1",
"short": "a",
"long": "ace",
"type": "string",
"required": False
}, {
"name": "thename2",
"short": "b",
"long": "bravo",
"type": "number",
"required": True
}, {
"name": "thename3",
"short": "c",
"long": "candy",
"type": "array",
"required": True
}
]
@click.group()
def cli():
pass
@cli.command()
@options_from_db(run_options)
@click.argument('url')
def run(*args, **kwargs):
click.echo('args: {}'.format(args) )
click.echo('kwargs: {}'.format(kwargs))
if __name__ == "__main__":
commands = (
'run www.mysite.com/api/get -a testparam --bravo 5 -c item1 item2',
'',
'--help',
'run --help',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for cmd in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + cmd)
time.sleep(0.1)
cli(cmd.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> run www.mysite.com/api/get -a testparam --bravo 5 -c item1 item2
args: ()
kwargs: {'thename1': 'testparam', 'thename2': 5.0, 'thename3': ('item1', 'item2'), 'url': 'www.mysite.com/api/get'}
-----------
>
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
run
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
run
-----------
> run --help
Usage: test.py run [OPTIONS] URL
Options:
-a, --ace TEXT
-b, --bravo FLOAT [required]
-c, --candy TEXT [required]
--help Show this message and exit.
关于python - 动态指定选项和参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50499340/
简而言之:我想从可变参数模板参数中提取各种选项,但不仅通过标签而且通过那些参数的索引,这些参数是未知的 标签。我喜欢 boost 中的方法(例如 heap 或 lockfree 策略),但想让它与 S
我可以对单元格中的 excel IF 语句提供一些帮助吗? 它在做什么? 对“BaselineAmount”进行了哪些评估? =IF(BaselineAmount, (Variance/Baselin
我正在使用以下方法: public async Task Save(Foo foo,out int param) { ....... MySqlParameter prmparamID
我正在使用 CodeGear RAD Studio IDE。 为了使用命令行参数测试我的应用程序,我多次使用了“运行 -> 参数”菜单中的“参数”字段。 但是每次我给它提供一个新值时,它都无法从“下拉
我已经为信用卡类编写了一些代码,粘贴在下面。我有一个接受上述变量的构造函数,并且正在研究一些方法将这些变量格式化为字符串,以便最终输出将类似于 号码:1234 5678 9012 3456 截止日期:
MySql IN 参数 - 在存储过程中使用时,VarChar IN 参数 val 是否需要单引号? 我已经像平常一样创建了经典 ASP 代码,但我没有更新该列。 我需要引用 VarChar 参数吗?
给出了下面的开始,但似乎不知道如何完成它。本质上,如果我调用 myTest([one, Two, Three], 2); 它应该返回元素 third。必须使用for循环来找到我的解决方案。 funct
将 1113355579999 作为参数传递时,该值在函数内部变为 959050335。 调用(main.c): printf("%d\n", FindCommonDigit(111335557999
这个问题在这里已经有了答案: Is Java "pass-by-reference" or "pass-by-value"? (92 个回答) 关闭9年前。 public class StackOve
我真的很困惑,当像 1 == scanf("%lg", &entry) 交换为 scanf("%lg", &entry) == 1 没有区别。我的实验书上说的是前者,而我觉得后者是可以理解的。 1 =
我正在尝试使用调用 SetupDiGetDeviceRegistryProperty 的函数使用德尔福 7。该调用来自示例函数 SetupEnumAvailableComPorts .它看起来像这样:
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
rails 新手。按照多态关联的教程,我遇到了这个以在create 和destroy 中设置@client。 @client = Client.find(params[:client_id] || p
通过将 VM 参数设置为 -Xmx1024m,我能够通过 Eclipse 运行 Java 程序-Xms256M。现在我想通过 Windows 中的 .bat 文件运行相同的 Java 程序 (jar)
我有一个 Delphi DLL,它在被 Delphi 应用程序调用时工作并导出声明为的方法: Procedure ProduceOutput(request,inputs:widestring; va
浏览完文档和示例后,我还没有弄清楚 schema.yaml 文件中的参数到底用在哪里。 在此处使用 AWS 代码示例:https://github.com/aws-samples/aws-proton
程序参数: procedure get_user_profile ( i_attuid in ras_user.attuid%type, i_data_group in data_g
我有一个字符串作为参数传递给我的存储过程。 dim AgentString as String = " 'test1', 'test2', 'test3' " 我想在 IN 中使用该参数声明。 AND
这个问题已经有答案了: When should I use "this" in a class? (17 个回答) 已关闭 6 年前。 我运行了一些java代码,我看到了一些我不太明白的东西。为什么下
我输入 scroll(0,10,200,10);但是当它运行时,它会传递字符串“xxpos”或“yypos”,我确实在没有撇号的情况下尝试过,但它就是行不通。 scroll = function(xp
我是一名优秀的程序员,十分优秀!