【问题标题】:Creating a Click.Option with prompt that shows only if default value is empty创建一个带有提示的 Click.Option,仅在默认值为空时显示
【发布时间】:2018-02-02 17:53:28
【问题描述】:

给定以下选项:

@cli.command()
@click.option('--param', default=lambda: get_value(), prompt="Enter Param")

正常行为是单击以显示提示输入 param 的值并显示默认值(您只需通过它输入即可保留该值)。

相反,我希望param 提示仅显示get_value() 是否返回None 或一些预定义的“显示”值,但对于get_value() 的任何真值/其他值,单击不会显示提示输入此选项并运行命令或移至下一个提示符。

【问题讨论】:

    标签: python python-click


    【解决方案1】:
    class OptionPromptNull(click.Option):
        _value_key = '_default_val'
    
        def get_default(self, ctx):
            if not hasattr(self, self._value_key):
                default = super(OptionPromptNull, self).get_default(ctx)
                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.command()
    @click.option('--tenant', '-t', cls=OptionPromptNull, default=Config.TENANT_NAME, prompt='Please enter tenant name', help='MindSphere tenant name')
    @click.option('--client_id', '-ci', cls=OptionPromptNull, default=Config.CLIENT_ID, prompt='Please enter client id', help='MindSphere service account client id')
    @click.option('--client_secret', '-cs', hide_input=True, cls=OptionPromptNull, default=Config.CLIENT_SECRET, prompt='Please enter client secret (it will be hidden while you type & kept secretly)', help='MindSphere service account client secret')
    @click.option('--key', '-k', cls=OptionPromptNull, default=Config.ENCRYPTION_KEY, prompt='Please enter any secret key', help='Secret key used to store sensitive information in encrypted format ')
    @click.option('--config_file', '-cf', cls=OptionPromptNull, default=Config.DEFAULT_CONFIG_FILE, prompt='Please enter config file path', help='Specific config file to execute MindSphere tasks')
    def setup(tenant, client_id, client_secret, key, config_file):
        pass
    
    
    @click.group()
    def cli():
        pass
    
    

    【讨论】:

    • 嗨,Dinesh,你为什么重复上面的答案?从字面上使用相同的代码。另请注意,答案已经得到解答。如果您有什么要补充的,请在原始答案的评论中这样做
    【解决方案2】:

    这可以通过覆盖click.Option.get_default()click.Option.prompt_for_value() 方法来完成,例如:

    自定义类:

    import click
    
    class OptionPromptNull(click.Option):
        _value_key = '_default_val'
    
        def get_default(self, ctx):
            if not hasattr(self, self._value_key):
                default = super(OptionPromptNull, self).get_default(ctx)
                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
    

    使用自定义类:

    然后要使用自定义类,请将其作为 cls 参数传递给选项装饰器,例如:

    @click.command()
    @click.option('--param', cls=OptionPromptNull,
                  default=lambda: get_value(), prompt="Enter Param")
    def cli(param):
        click.echo("param: '{}'".format(param))
    

    测试代码:

    @click.command()
    @click.option('--param1', cls=OptionPromptNull,
                  default=lambda: get_value_none(), prompt="Enter Param1")
    @click.option('--param2', cls=OptionPromptNull,
                  default=lambda: get_value_one(), prompt="Enter Param2")
    def cli(param1, param2):
        click.echo("param1: '{}'".format(param1))
        click.echo("param2: '{}'".format(param2))
    
    
    def get_value_none():
        return None
    
    def get_value_one():
        return 1
    
    cli([])
    

    结果:

    Enter Param1: 23
    param1: '23'
    param2: '1'
    

    【讨论】:

    • 抱歉耽搁了,不知何故错过了答案通知,效果很好!
    • 如果get_value_one() 需要导入另一个参数怎么办?例如get_value_one(otherclickparam)?
    • 您希望 get_value_one() 使用另一个(先前)参数进行评估?这听起来是个很好的问题!我想这是可行的,但会比上述更多。你应该写一个新问题。如果您愿意,可以在此处发表评论并附上该问题的链接,以便我一定会看到。
    • 是的。这就是我要找的。在这里发布了一个问题:stackoverflow.com/questions/51846634/…
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2016-05-12
    • 1970-01-01
    • 2013-05-15
    相关资源
    最近更新 更多