单击-基于其他选项的提示动态默认值 [英] Click - Dynamic Defaults for Prompts based on other options

查看:99
本文介绍了单击-基于其他选项的提示动态默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用单击来构建CLI界面.单击提供的提示的动态默认值,非常好.另外,此示例给出了一些有关如何使用自定义点击类实现动态默认设置的见解,从而在评估时提供了更灵活的选项默认值.

I'm using Click to build a CLI interface. Click offers dynamic defaults for prompts, which is great. Also this example gives some insights on how to implement dynamic defaults using a custom click-class and thus provide more flexible options when evaluating the default value.

我现在要做的是根据另一个提供的点击选项(例如,

What I'm trying to do now is to have dynamic defaults based on another provided click option, e.g.

python mymodule --param1 something --param2 somethingelse

现在,如果param2为空,我想尝试根据提供的param1输入获得动态默认值,例如:

Now if param2 is empty I want to try to get a dynamic default based on the provided param1 input, e.g.:

@click.command()
@click.option('--param1', prompt=True)
@click.option('--param2', prompt=True, default=lambda: myfunct(param1))
def cmd(param1, param2):
    pass

myfunct(param1:str=None):
    param2 = None
    #get param2 based on param1 input
    return param2

关于完成这项工作的最佳方法的任何想法? 并保证在param2之前先评估(并提示)param1吗?

Any ideas on what would be the best way to get that done? And is it guaranteed that param1 is evaluated (and prompted for) before param2?

推荐答案

扩展您引用的示例所需的功能可以像这样完成:

Extending the example you referenced the desired functionality can be done like:

import click

class OptionPromptNull(click.Option):
    _value_key = '_default_val'

    def __init__(self, *args, **kwargs):
        self.default_option = kwargs.pop('default_option', None)
        super(OptionPromptNull, self).__init__(*args, **kwargs)

    def get_default(self, ctx):
        if not hasattr(self, self._value_key):
            if self.default_option is None:
                default = super(OptionPromptNull, self).get_default(ctx)
            else:
                arg = ctx.params[self.default_option]
                default = self.type_cast_value(ctx, self.default(arg))
            setattr(self, self._value_key, default)
        return getattr(self, self._value_key)

    def prompt_for_value(self, ctx):
        default = self.get_default(ctx)

        # only prompt if the default value is None
        if default is None:
            return super(OptionPromptNull, self).prompt_for_value(ctx)

        return default

使用自定义类:

要使用自定义类,您需要将三个参数传递给click.option装饰器,例如:

Using the Custom Class:

To use the custom class you need to pass three parameters to the click.option decorator like:

@click.option('--param3', cls=OptionPromptNull, default_option='param1',
              default=lambda x: get_a_value(x), prompt="Enter Param3")

  • cls需要引用自定义类.

    • cls need to reference the custom class.

      default_option需要指定哪个选项将传递给default可调用对象.

      default_option needs to specify which option will be passed to the default callable.

      default指定用于获取默认值的可调用对象.

      default specifies the callable used to get the default.

      之所以可行,是因为click是一个设计良好的OO框架. @click.option()装饰器通常会实例化click.Option对象,但允许使用cls参数覆盖此行为.因此,在我们自己的类中从click.Option继承并超越所需的方法是相对容易的事情.

      This works because click is a well designed OO framework. The @click.option() decorator usually instantiates a click.Option object but allows this behavior to be over ridden with the cls parameter. So it is a relatively easy matter to inherit from click.Option in our own class and over ride desired methods.

      在这种情况下,我们超越了click.Option.get_default()click.Option.prompt_for_value()方法.在prompt_for_value()中,我们仅提示默认值为None.然后在get_default()中,我们调用default函数,以传递所需的(先前输入的)参数.

      In this case we over ride the click.Option.get_default() and the click.Option.prompt_for_value() methods. In prompt_for_value() we only prompt if the default is None. And then in get_default() we call the default function passing the desired (previously entered) param.

      为阐明问题的一部分,首先评估选项:按在命令行上传递的顺序,然后对选项进行评估:对于未在命令行上传递的选项,按声明的顺序进行./p>

      测试代码:

      And to clarify one part of the question, the options are evaluated first: in the order they were passed on the command line, and second: in the order they were declared for those that were not passed on the command line.

      @click.command()
      @click.option('--param1', prompt="Enter Param1")
      @click.option('--param2', cls=OptionPromptNull,
                    default=lambda: get_value_none(), prompt="Enter Param2")
      @click.option('--param3', cls=OptionPromptNull, default_option='param1',
                    default=lambda x: get_a_value(x), prompt="Enter Param3")
      def cli(param1, param2, param3):
          click.echo("param1: '{}'".format(param1))
          click.echo("param2: '{}'".format(param2))
          click.echo("param3: '{}'".format(param3))
      
      
      def get_value_none():
          return None
      
      def get_a_value(val):
          return val
      
      if __name__ == "__main__":
          commands = (
              r'',
              r'--param3 5',
              '--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)]
      -----------
      > 
      Enter Param1: 3
      Enter Param2: 4
      param1: '3'
      param2: '4'
      param3: '3'
      -----------
      > --param3 5
      Enter Param1: 3
      Enter Param2: 4
      param1: '3'
      param2: '4'
      param3: '5'
      -----------
      > --help
      Usage: test.py [OPTIONS]
      
      Options:
        --param1 TEXT
        --param2 TEXT
        --param3 TEXT
        --help         Show this message and exit.
      

      这篇关于单击-基于其他选项的提示动态默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆