如何删除该参数处理代码的重复数据?

问题描述 投票:2回答:2

我有以下代码在最终调用matplotlib的脚本中从命令行设置y和x轴限制(这里ax是matplotlib axes对象,但实际上没关系,并且[ C0]是p实例):

ArgumentParser

[如果您相信p.add_argument('--ylim', help='Set the y axis limits explicitly (e.g., to cross at zero)', type=float, nargs='+') p.add_argument('--xlim', help='Set the x axis limits explicitly', type=float, nargs='+') # more stuff if args.ylim: if (len(args.ylim) == 1): ax.set_ylim(args.ylim[0]) elif (len(args.ylim) == 2): ax.set_ylim(args.ylim[0], args.ylim[1]) else: sys.exit('provide one or two args to --ylim') if args.xlim: if (len(args.xlim) == 1): ax.set_xlim(args.xlim[0]) elif (len(args.xlim) == 2): ax.set_xlim(args.xlim[0], args.xlim[1]) else: sys.exit('provide one or two args to --xlim') 可能会使您的眼睛发烧:这两个块是相同的,除了DRY在第二个地方都替换了xlim

如何重构它以删除重复项?我曾两次调用某种限位设置功能似乎很明显,但是例如,如何传递我想在一种情况下调用ylim而在另一种情况下调用set_ylim的事实呢?

python python-3.x refactoring argparse dry
2个回答
3
投票

函数是一流的对象。如果在不调用的情况下编写set_xlim,则会获得对ax.set_ylim函数的引用,该函数绑定到set_ylim()

ax

1
投票

有两个使用argparse的选项:

定义一个自定义操作,该操作将值的数量限制为指定范围,如def check(name, lim, setter) if not lim: return if (len(lim) == 1): setter(lim[0]) elif (len(lim) == 2): setter(lim[0], lim[1]) else: sys.exit(f'provide one or two args to {name}') check('--ylim', args.ylim, ax.set_ylim) check('--xlim', args.xlim, ax.set_xlim) 中所示>

这具有在传入参数的上下文中处理错误的优势;并且因为您的输入应该可以接受,所以您可以解压缩args。

Python argparse: Is there a way to specify a range in nargs?

或者,您可以允许输入长度为一个或多个(# From: https://stackoverflow.com/a/4195302/3279716 def required_length(nmin,nmax): class RequiredLength(argparse.Action): def __call__(self, parser, args, values, option_string=None): if not nmin<=len(values)<=nmax: msg='argument "{f}" requires between {nmin} and {nmax} arguments'.format( f=self.dest,nmin=nmin,nmax=nmax) raise argparse.ArgumentTypeError(msg) setattr(args, self.dest, values) return RequiredLength # Make parser parser=argparse.ArgumentParser(prog='PROG') parser.add_argument('--xlim', nargs='+', type=int, action=required_length(1,2)) parser.add_argument('--ylim', nargs='+', type=int, action=required_length(1,2)) # Use args in code ax.set_xlim(*args.xlim) ax.set_ylim(*args.ylim) ),然后仅手动检查输入的长度并在需要时引发解析器错误:

nargs=“+”
© www.soinside.com 2019 - 2024. All rights reserved.