首页 > 解决方案 > 如果给出空参数,如何处理 sys.argv

问题描述

我在脚本中使用 sys.argv 遇到了这个问题。

该脚本包含几个函数来分类、构建​​和转换数据集,没什么大不了的。

在脚本的开头,我根据参数将外部参数分配给 2 或 3 个变量。

if len(sys.argv) > 2:
    nfcv=sys.argv[1]
    pgrid = [int(x) for x in sys.argv[2].split(",")]
    refit =  sys.argv[3]
else:
    nfcv=sys.argv[1]
    pgrid = [int(x) for x in sys.argv[2].split(",")]
    refit =  ""

在命令行下方运行带有所有 3 个参数的脚本。

OC_run_eval_ML.py 5 "2,4,6,8,10,12,14" y

在脚本执行期间,我只想在 3 参数 =“y”时才适合我的分类器,如果为空则通过

低于我所做的

def fit(X,y):
    clf.fit(X, y)

if refit == "y" :
    fit(X_train_std,y_train)
else: pass

没有第三个参数(这意味着我不想“适合”我的模型)

OC_run_eval_ML.py 5 "2,4,6,8,10,12,14"

我收到以下错误消息:

Traceback (most recent call last):
  File "OC_run_eval_ML.py", line 25, in <module>
    refit =  sys.argv[3]
IndexError: list index out of range

似乎不接受条件:“len(sys.argv)> 2:”

欢迎帮助。

先感谢您。

Rgds

标签: pythonarguments

解决方案


sys.argv列表始​​终包含脚本名称作为第一个参数,因此当您有 3 个命令行参数时, 的长度sys.argv将为4 个元素。len(sys.argv) > 2如果也只有 3 个元素,则为 true。

测试3个或更多:

if len(sys.argv) > 3:
    nfcv=sys.argv[1]
    pgrid = [int(x) for x in sys.argv[2].split(",")]
    refit =  sys.argv[3]
else:
    nfcv=sys.argv[1]
    pgrid = [int(x) for x in sys.argv[2].split(",")]
    refit =  ""

您可以将其简化为:

nfcv = sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
if len(sys.argv) > 3:
    refit =  sys.argv[3]
else:
    refit =  ""

就个人而言,我会使用该argparse为您完成这项工作,或者(对于更复杂的项目)使用click.

解析示例:

import argparse

parser = argparse.ArgumentParser(description='Classify, build and transform a dataset')
parser.add_argument("nfcv", help="The NFCV argument...")
parser.add_argument("pgrid", 
    help="Comma-separated pgrid values",
    type=lambda v: [int(x) for x in v.split(",")]
)
parser.add_argument("refit", nargs="?", default="", help="The refit argument...")

args = parser.parse_args()

然后在您的代码中使用args.nfcv,args.pgrid和。args.refit

演示:

$ cat demo.py
import argparse

parser = argparse.ArgumentParser(description='Classify, build and transform a dataset')
parser.add_argument("nfcv", help="The NFCV argument...")
parser.add_argument("pgrid",
    help="Comma-separated pgrid values",
    type=lambda v: [int(x) for x in v.split(",")]
)
parser.add_argument("refit", nargs="?", default="", help="The refit argument...")

args = parser.parse_args()

print(f"NFCV:  {args.nfcv!r}")
print(f"prid:  {args.pgrid!r}")
print(f"refit: {args.refit!r}")

$ python3 demo.py --help
usage: demo.py [-h] nfcv pgrid [refit]

Classify, build and transform a dataset

positional arguments:
  nfcv        The NFCV argument...
  pgrid       Comma-separated pgrid values
  refit       The refit argument...

optional arguments:
  -h, --help  show this help message and exit
$ python3 demo.py foo 42,81,117
NFCV:  'foo'
prid:  [42, 81, 117]
refit: ''
$ python3 demo.py foo 42,81,117 y
NFCV:  'foo'
prid:  [42, 81, 117]
refit: 'y'

请注意,如果refit是一个switch,那么只需使用一个store_true动作并将其作为-r/--refit命令行参数:

parser.add_argument(
    '-r', '--refit', action='store_true', default=False,
    help="Enable refit"
)

而不是parser.add_argument('refit', ...)线。在这种情况下args.refit,默认为False并且在命令行上使用-r--refit正在使用的布尔值设置为True. 然后只是if args.refit:用来测试它。

具有该更改的演示如下所示:

$ python3 demo.py --help
usage: demo.py [-h] [-r] nfcv pgrid

Classify, build and transform a dataset

positional arguments:
  nfcv         The NFCV argument...
  pgrid        Comma-separated pgrid values

optional arguments:
  -h, --help   show this help message and exit
  -r, --refit  Enable refit
$ python3 demo.py foo 42,81,117
NFCV:  'foo'
prid:  [42, 81, 117]
refit: False
$ python3 demo.py foo 42,81,117 --refit
NFCV:  'foo'
prid:  [42, 81, 117]
refit: True

推荐阅读