我有以下代码在最终调用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
的事实呢?
函数是一流的对象。如果在不调用的情况下编写set_xlim
,则会获得对ax.set_ylim
函数的引用,该函数绑定到set_ylim()
。
ax
有两个使用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=“+”