5

我正在使用Python 2开发一个小型命令行工具,然后单击. 我的工具要么需要写入一个值,要么读取它,要么不更改它。如果我能做到以下几点就好了:

mytool --r0=0xffff..........将值设置r00xffff
mytool --r0......................读取值 r0
mytool.... ..........不要做任何事情r0

根据文档,这似乎不可能,但我可能会错过它。那么有可能还是我必须找到不同的方法?

4

2 回答 2

2

基于@Stephen Rauch 的回答,我想我找到了一个更简单的解决方案

代码

class CommandWithOptionalFlagValues(click.Command):
    def parse_args(self, ctx, args):
        """ Translate any flag `--opt=value` as flag `--opt` with changed flag_value=value """
        # filter flags
        flags = [o for o in self.params if o.is_flag and not isinstance(o.flag_value, bool)]
        prefixes = {p: o for o in flags for p in o.opts if p.startswith('--')}
        for i, flag in enumerate(args):
            flag = flag.split('=')
            if flag[0] in prefixes and len(flag) > 1:
                prefixes[flag[0]].flag_value = flag[1]
                args[i] = flag[0]

        return super(CommandWithOptionalFlagValues, self).parse_args(ctx, args)

测试

@click.command(cls=CommandWithOptionalFlagValues)
@click.option('--r0', is_flag=True, help='set or use default r0 value', flag_value=3.0)
@click.option('--r1', is_flag=True, help='Enable r1')
def cli(r0, r1):
    click.echo('r0: {} r1: {}'.format(r0, r1))

cli(['--r1'])
cli(['--r0', '--r1'])
cli(['--r0=5.0'])

结果

r0: None r1: True
r0: 3.0 r1: True
r0: 5.0 r1: False
于 2021-08-20T19:40:09.413 回答
1

解决此问题的一种方法是引入另一个名为r0_set. 然后为了保留想要的命令行,我们可以继承click.Command并覆盖rideparse_args来把用户r0=0xffff输入r0_set=0xffff

代码:

class RegisterReaderOption(click.Option):
    """ Mark this option as getting a _set option """
    register_reader = True

class RegisterWriterOption(click.Option):
    """ Fix the help for the _set suffix """
    def get_help_record(self, ctx):
        help = super(RegisterWriterOption, self).get_help_record(ctx)
        return (help[0].replace('_set ', '='),) + help[1:]

class RegisterWriterCommand(click.Command):
    def parse_args(self, ctx, args):
        """ Translate any opt= to opt_set= as needed """
        options = [o for o in ctx.command.params
                   if getattr(o, 'register_reader', None)]
        prefixes = {p for p in sum([o.opts for o in options], [])
                    if p.startswith('--')}
        for i, a in enumerate(args):
            a = a.split('=')
            if a[0] in prefixes and len(a) > 1:
                a[0] += '_set'
                args[i] = '='.join(a)

        return super(RegisterWriterCommand, self).parse_args(ctx, args)

测试代码:

@click.command(cls=RegisterWriterCommand)
@click.option('--r0', cls=RegisterReaderOption, is_flag=True,
              help='Read the r0 value')
@click.option('--r0_set', cls=RegisterWriterOption,
              help='Set the r0 value')
def cli(r0, r0_set):
    click.echo('r0: {}  r0_set: {}'.format(r0, r0_set))

cli(['--r0=0xfff', '--r0'])
cli(['--help'])

结果:

r0: True  r0_set: 0xfff

Usage: test.py [OPTIONS]

Options:
  --r0       Read the r0 value
  --r0=TEXT  Set the r0 value
  --help     Show this message and exit.
于 2017-05-23T20:06:45.820 回答