argparse:作为标志和变量的可选参数

argparse: optional argument as flag and variable

我正在编写一个程序,它接受两个参数(路径)并作为一个选项 -l, 可以将日志保存在日志文件中。

我正在使用 argparse 并创建以下参数:

parser.add_argument('-l', '--logfile', 
                    nargs='?', 
                    const='tranfer.log', 
                    default=False,
                    help='save log of the transfer')

这些是使用形式:

  1. prog.py path_1 path_2。没什么特别的。
  2. prog.py -l filename path_1 path_2。将日志保存在 filename 文件中。
  3. prog.py -l path_1 path_2。默认保存日志文件(比如,logfile)。

我在第 3 项中遇到问题,因为 prog.pypath_1 作为日志文件的文件名。这个问题很容易解决,在行尾输入 -l 选项。

prog.py path_1 path_2 -l

但我想知道是否有办法告诉 argparse 使用最后两个选项作为路径文件,因为我不是唯一使用该程序的人。

路径参数添加如下:

parser.add_argument('left_path', 
                    action='store',
                    help='first path')
parser.add_argument('right_path', 
                    action='store',
                    help='second path')

做到这一点的巧妙方法是也为两个路径参数引入选项标志。这样就没有歧义了,你可以说:

prog.py -l -leftpath path_1 -rightpath path_2

您还可以将所有选项存储在一个参数中并手动检查,如

parser.add_argument('-p', dest='path', nargs='?',
                    default=('path1/','path2/'))
args = parser.parse_args()
if len(args.path) == 3:
   args.logfile = args.path[0]
   args.path = args.path[1:]
elif len(args.path) == 2:
   args.logfile = ''
else:
   print 'Error'

但是如果要将路径设置为与默认路径不同,则必须具有 -p 标志。

你的评价是对的,

prog.py -l path_1 path_2

会将 path_1 分配给 l 并将 path_2 分配给第一个位置,并引发有关缺少第二个位置的错误。

http://bugs.python.org/issue9338 argparse optionals with nargs='?', '*' or '+' can't be followed by positionals 是处理此问题的 bug/issue。已提出补丁,但未实施。这不是微不足道的。当处理 -l 时,解析器必须向前看,看看需要多少参数来满足位置,并避免使用下一个字符串(即使根据您的定义,它完全有权这样做)。

在之前的 SO 问题中也讨论过。

您必须将可选参数放在最后,或者使用其他一些方式来表示其参数列表的结尾(-- 或其他标记的可选参数)。或更改参数定义,使 -l 不是 ?(或等效项),或将位置更改为已标记。