Python argparse:命令行值未针对可选值初始化
Posted
技术标签:
【中文标题】Python argparse:命令行值未针对可选值初始化【英文标题】:Python argparse: command lines values are not initialised for optional values 【发布时间】:2021-06-26 20:36:56 【问题描述】:我有以下要使用 argparse 解析的参数
input_dir(字符串:强制) output_dir(字符串:强制) file_path(字符串:强制) supported_file_extensions(逗号分隔字符串 - 可选) ignore_tests(布尔值 - 可选)如果分别为supported_file_extensions
和ignore_tests
提供了逗号分隔的字符串和字符串,那么我希望将值设置为参数变量。我的设置如下
import sys
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'input_dir', type=str,
help='Fully qualified directory for the input directory')
parser.add_argument(
'file_path', type=str,
help='Fully qualified path name for file')
parser.add_argument(
'output', type=str, help='Fully qualified output directory path')
parser.add_argument(
'-supported_file_extensions',nargs='?', type=str, default=None,
help='optional comma separated file extensions'
) # Should default to False
parser.add_argument(
'-ignore_tests', nargs='?', type=bool, default=True
) # Should default to True if the argument is passed
(arguments, _) = parser.parse_known_args(sys.argv[1:])
print(arguments)
当我通过以下命令时
python cloc.py -input_dir /myproject -file_path /myproject/.github/CODEOWNERS -output output.json --supported_file_extensions java,kt --ignore_tests False
我希望参数的值。--supported_file_extensions 等于 java,kt
和 ignore_tests
等于 False
但我得到以下值
Namespace(file_path='/myproject/.github/CODEOWNERS', ignore_tests=True, input_dir='/myproject', output='output.json', supported_file_extensions=None)
如果我没有在命令行参数中传递--ignored_tests
,那么我希望文件默认为False
。同样,当我传递--ignored_tests
时,我希望将参数设置为True
。
如果我传递--supported_file_extensions java,kt
,那么我希望将参数设置为java,kt
作为字符串,而不是列表。
我尝试过,但没有成功。
-
Python argparse: default value or specified value
python argparse default value for optional argument
Creating command lines with python (argparse)
更新 我将最后两个参数更新如下:
parser.add_argument(
'-supported_file_extensions', type=str,
help='optional comma separated file extensions'
)
parser.add_argument(
'-ignore_tests', action='store_true',
help='optional flag to ignore '
)
(arguments, _) = parser.parse_known_args(sys.argv[1:])
print(arguments)
当我运行命令时
python cloc.py -input_dir /myproject -file_path /myproject/.github/CODEOWNERS -output output.json --supported_file_extensions java,kt
输出如下
Namespace(file_path='/myproject/.github/CODEOWNERS', ignore_tests=False, input_dir='/myproject', output='output.json', supported_file_extensions=None)
虽然ignore_tests
的值是正确的(默认为false),但supported_file_extensions
的值是None
,这是不正确的,因为我已将java,kt
作为命令行参数传递。
当我通过时
python cloc.py -input_dir /myproject -file_path /myproject/.github/CODEOWNERS -output output.json --supported_file_extensions java,kt --ignore_tests
我得到以下输出
Namespace(file_path='/myproject/.github/CODEOWNERS', ignore_tests=False, input_dir='/myproject', output='output.json', supported_file_extensions=None)
【问题讨论】:
用户是否有某些原因必须通过True
或False
?让他们通过开关,或者不通过,没有任何价值,这是一个好多更好的主意。 action='store_true'
操作将使其“正常工作”,无需定义 type
、default
或 nargs
。您绝对不能使用bool
构造函数,因为bool("True")
和bool("False")
都为真(字符串上的bool
只有在字符串为空时才为假)。
'--ignore-test' 应该是action='store_true'
。 (或“store_false”)不要使用type=bool
。下定决心,标记的 st 3 args postional 是 '--input_dir'
@ShadowRanger 没有要求。我想要一种根据命令行参数将 True 或 False 初始化为 ignore_tests
的方法。
当我在不带参数的 Linux 上运行代码时,它会显示带有 -supported_file_extensions
的帮助消息,它有一个 -
,但你使用双 --
运行它。如果我使用双 --supported_file_extensions
运行它,那么我会得到 None
但如果我使用单 -supported_file_extensions
,那么它会给出正确的值。您只是以错误的方式使用-
。您应该使用单 -output
和双 --supported_file_extensions
如果您定义add_argument('output')
,那么它期望没有-output
的值。如果您使用单个 -
定义,例如 add_argument('-supported_file_extensions')
,那么您也应该使用单个 -
来运行它,例如 -supported_file_extensions value
。如果你想使用 double --
like --supported_file_extensions value
那么你应该定义 double --
like add_argument('--supported_file_extensions')
【参考方案1】:
你的论点不正确。您将参数注册到解析器为-ignore_tests
,但在命令行上将其指定为--ignore_tests
——注意前面的破折号的数量。您也不需要为位置参数指定-input_dir
,它们什么都不做。
通常,上述两个问题都会导致您的脚本崩溃。它仍然运行的唯一原因是因为您使用的是parser.parse_known_args
,它会忽略所有它不理解的参数——比如--ignore_tests
和-input_dir
。
你应该运行的命令是:
python cloc.py /myproject /myproject/.github/CODEOWNERS output.json -supported_file_extensions java,kt -ignore_tests False
此外,正如许多 cmets 所提到的,在注册参数时不要使用type=bool
。相反,使用
parser.add_argument('-ignore_tests', action='store_true')
当存在-ignore_tests
时,这会将ignore_tests
设置为True
,否则设置False
— 无需在命令行上显式指定True
或False
。
【讨论】:
【参考方案2】:我认为这是一个更好的定义:
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'--input_dir',
help='Fully qualified directory for the input directory')
parser.add_argument(
'--file_path',
help='Fully qualified path name for file')
parser.add_argument(
'--output', help='Fully qualified output directory path')
parser.add_argument(
'--supported_file_extensions',
help='optional comma separated file extensions'
) # only use ? if defining default and const
parser.add_argument(
'--ignore_tests', action='store_true'
)
(arguments, extras) = parser.parse_known_args()
print(arguments)
print(extras)
致电:
python cloc.py --input_dir /myproject --file_path /myproject/.github/CODEOWNERS --output output.json --supported_file_extensions java,kt
另一个版本:
如果 name == 'main': parser = argparse.ArgumentParser()
parser.add_argument(
'--supported_file_extensions',
help='optional comma separated file extensions')
parser.add_argument(
'--ignore_tests', action='store_true')
parser.add_argument(
'input_dir',
help='Fully qualified directory for the input directory')
parser.add_argument(
'file_path',
help='Fully qualified path name for file')
parser.add_argument(
'output', help='Fully qualified output directory path')
(arguments, extras) = parser.parse_known_args()
print(arguments)
print(extras)
致电:
python cloc.py --ignore_tests /myproject /myproject/.github/CODEOWNERS output.json --supported_file_extensions java,kt
optionals
(--) 可以按任何顺序排列,但positionals
必须按给定顺序排列。 positionals
没有标志或关键字。
【讨论】:
我希望能够传递命令行键。command line keys
是什么意思?测试我的代码并查看Namespace
。如果你想要不同的行为,你可能想直接解析sys.argv
。
我可能错了,但如果有人通过--key value
,那么这意味着这些值是可选的,不是吗?我希望前三个是强制性的。
你可以设置required=True
。或者只是给他们合理的默认值,所以你不在乎。或者让他们positionals
(但是你不能在输入中使用标志词)。
您的建议对我有用。如果您可以使用required=True
更新您的答案,那么我可以接受。以上是关于Python argparse:命令行值未针对可选值初始化的主要内容,如果未能解决你的问题,请参考以下文章