未提供参数时的python argparse集行为
我对python还相当陌生,在使用命令行参数时,我一直在研究如何构造我的简单脚本 脚本的目的是自动化我工作中与排序和操作图像相关的一些日常任务 我可以指定参数并让它们调用相关函数,但我还希望在没有提供参数时设置默认操作 这是我目前的结构未提供参数时的python argparse集行为,python,python-2.7,argparse,Python,Python 2.7,Argparse,我对python还相当陌生,在使用命令行参数时,我一直在研究如何构造我的简单脚本 脚本的目的是自动化我工作中与排序和操作图像相关的一些日常任务 我可以指定参数并让它们调用相关函数,但我还希望在没有提供参数时设置默认操作 这是我目前的结构 parser = argparse.ArgumentParser() parser.add_argument("-l", "--list", help="Create CSV of images", action="store_true") parser.add
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--list", help="Create CSV of images", action="store_true")
parser.add_argument("-d", "--dimensions", help="Copy images with incorrect dimensions to new directory", action="store_true")
parser.add_argument("-i", "--interactive", help="Run script in interactive mode", action="store_true")
args = parser.parse_args()
if args.list:
func1()
if args.interactive:
func2()
if args.dimensions:
func3()
但当我不提供任何论据时,就不会调用任何东西
Namespace(dimensions=False, interactive=False, list=False)
如果没有提供参数,我想要的是一些默认行为
if args.list:
func1()
if args.interactive:
func2()
if args.dimensions:
func3()
if no args supplied:
func1()
func2()
func3()
这看起来应该很容易实现,但我对如何检测所有参数都是错误的逻辑感到迷茫,而不必循环遍历参数并测试所有参数是否都是错误的
更新
多个参数一起是有效的,这就是为什么我没有走elif路线
更新2
这是我的更新代码,考虑了@unutbu的答案
这似乎并不理想,因为所有内容都包含在if语句中,但短期内我找不到更好的解决方案。我很高兴接受@unutbu的答复,如有任何其他改进,将不胜感激
lists = analyseImages()
if lists:
statusTable(lists)
createCsvPartial = partial(createCsv, lists['file_list'])
controlInputParital = partial(controlInput, lists)
resizeImagePartial = partial(resizeImage, lists['resized'])
optimiseImagePartial = partial(optimiseImage, lists['size_issues'])
dimensionIssuesPartial = partial(dimensionIssues, lists['dim_issues'])
parser = argparse.ArgumentParser()
parser.add_argument(
"-l", "--list",
dest='funcs', action="append_const", const=createCsvPartial,
help="Create CSV of images",)
parser.add_argument(
"-c", "--convert",
dest='funcs', action="append_const", const=resizeImagePartial,
help="Convert images from 1500 x 2000px to 900 x 1200px ",)
parser.add_argument(
"-o", "--optimise",
dest='funcs', action="append_const", const=optimiseImagePartial,
help="Optimise filesize for 900 x 1200px images",)
parser.add_argument(
"-d", "--dimensions",
dest='funcs', action="append_const", const=dimensionIssuesPartial,
help="Copy images with incorrect dimensions to new directory",)
parser.add_argument(
"-i", "--interactive",
dest='funcs', action="append_const", const=controlInputParital,
help="Run script in interactive mode",)
args = parser.parse_args()
if not args.funcs:
args.funcs = [createCsvPartial, resizeImagePartial, optimiseImagePartial, dimensionIssuesPartial]
for func in args.funcs:
func()
else:
print 'No jpegs found'
这就是你想要的吗
if args.list:
func1()
if args.interactive:
func2()
if args.dimensions:
func3()
if not any(vars(args).values()):
func1()
func2()
func3()
(感谢@J.F.Sebastian提供
any
版本)您可以将funcs附加到属性args.funcs
,然后在未设置选项时使用一个if语句提供默认行为:
if not args.funcs:
args.funcs = [func1, func2, func3]
请注意,与原始代码不同,这允许用户控制调用函数的顺序:
% test.py -i -d
func2
func3
这可能是可取的,也可能不是可取的
作为对更新2的响应:
你的代码可以正常工作。但是,这里有另一种组织方式:
- 与将主程序嵌套在
if
子句中不同,您可以
使用
将打印未找到JPEG
到stderr
并以退出代码1终止
- 虽然我最初建议使用
functools.partial
,但现在我想到了另一种可能更简单的方法:代替
for func in args.funcs:
func()
我们可以说
for func, args in args.funcs:
func(args)
我们所需要做的就是将一个元组(func,args)
存储在args.func
而不仅仅是函数
例如:
import argparse
import sys
def parse_args(lists):
funcs = {
'createCsv': (createCsv, lists['file_list']),
'resizeImage': (resizeImage, lists['resized']),
'optimiseImage': (optimiseImage, lists['size_issues']),
'dimensionIssues': (dimensionIssues, lists['dim_issues']),
'controlInput': (controlInput, lists)
}
parser = argparse.ArgumentParser()
parser.add_argument(
"-l", "--list",
dest='funcs', action="append_const", const=funcs['createCsv'],
help="Create CSV of images",)
parser.add_argument(
"-c", "--convert",
dest='funcs', action="append_const", const=funcs['resizeImage'],
help="Convert images from 1500 x 2000px to 900 x 1200px ",)
parser.add_argument(
"-o", "--optimise",
dest='funcs', action="append_const", const=funcs['optimiseImage'],
help="Optimise filesize for 900 x 1200px images",)
parser.add_argument(
"-d", "--dimensions",
dest='funcs', action="append_const", const=funcs['dimensionIssues'],
help="Copy images with incorrect dimensions to new directory",)
parser.add_argument(
"-i", "--interactive",
dest='funcs', action="append_const", const=funcs['controlInput'],
help="Run script in interactive mode",)
args = parser.parse_args()
if not args.funcs:
args.funcs = [funcs[task] for task in
('createCsv', 'resizeImage', 'optimiseImage', 'dimensionIssues')]
return args
if __name__ == '__main__':
lists = analyseImages()
if not lists:
sys.exit('No jpegs found')
args = parse_args(lists)
statusTable(lists)
for func, args in args.funcs:
func(args)
您可以通过检查arg的数量是否等于1来处理此问题。这意味着只传递了python命令
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--list", help="Create CSV of images", action="store_true")
parser.add_argument("-d", "--dimensions", help="Copy images with incorrect dimensions to new directory", action="store_true")
parser.add_argument("-i", "--interactive", help="Run script in interactive mode", action="store_true")
args = parser.parse_args()
if len(sys.argv)==1:
# display help message when no args are passed.
parser.print_help()
sys.exit(1)
不,因为可能list
和interactive
都是有效的选项,然后需要调用两个函数。您好,Martijn,这是正确的,这就是为什么我远离elif路由的原因。这很完美,解决了我的问题。我将确保了解过滤器(无,变量(args).values())的含义:
没问题<代码>过滤器(无,iter)
表示序列中的所有真实项。错误的项目将被分类vars(args)
是作为字典的参数,而dict.values
是作为列表获取dict值的方法。如果没有(vars(args.values()):
总体而言,这似乎是一个更好的解决方案,但我接受的答案解决了我的问题。更详细一点,我不只是调用func1()
它更像func1(列出['file\u list'])
,这似乎与您的建议不符。我可以重新编辑这个问题使它更清楚。好的,没关系。如果您想知道如何使用预设参数“准备”函数,请查看。如果你想让我看看你重新编辑的问题,请留下一条指向“@unutbu”的评论,这样系统会通知我。我在考虑了你的建议后,对我的问题添加了一个更新。感谢您的帮助和functools.partial的链接。我准备接受你的回答,除非你有任何其他的改进建议@unutbu@d.learious:您的代码可以正常工作。然而,现在我想到了一种不用functools.partial的方法,我觉得它看起来更漂亮一些。我已经编辑了我的文章,上面,以显示我的意思。我接受了这个答案,因为它给了我更多的建议来推进和改进我的计划。谢谢你的帮助@unutbu
for func, args in args.funcs:
func(args)
import argparse
import sys
def parse_args(lists):
funcs = {
'createCsv': (createCsv, lists['file_list']),
'resizeImage': (resizeImage, lists['resized']),
'optimiseImage': (optimiseImage, lists['size_issues']),
'dimensionIssues': (dimensionIssues, lists['dim_issues']),
'controlInput': (controlInput, lists)
}
parser = argparse.ArgumentParser()
parser.add_argument(
"-l", "--list",
dest='funcs', action="append_const", const=funcs['createCsv'],
help="Create CSV of images",)
parser.add_argument(
"-c", "--convert",
dest='funcs', action="append_const", const=funcs['resizeImage'],
help="Convert images from 1500 x 2000px to 900 x 1200px ",)
parser.add_argument(
"-o", "--optimise",
dest='funcs', action="append_const", const=funcs['optimiseImage'],
help="Optimise filesize for 900 x 1200px images",)
parser.add_argument(
"-d", "--dimensions",
dest='funcs', action="append_const", const=funcs['dimensionIssues'],
help="Copy images with incorrect dimensions to new directory",)
parser.add_argument(
"-i", "--interactive",
dest='funcs', action="append_const", const=funcs['controlInput'],
help="Run script in interactive mode",)
args = parser.parse_args()
if not args.funcs:
args.funcs = [funcs[task] for task in
('createCsv', 'resizeImage', 'optimiseImage', 'dimensionIssues')]
return args
if __name__ == '__main__':
lists = analyseImages()
if not lists:
sys.exit('No jpegs found')
args = parse_args(lists)
statusTable(lists)
for func, args in args.funcs:
func(args)
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--list", help="Create CSV of images", action="store_true")
parser.add_argument("-d", "--dimensions", help="Copy images with incorrect dimensions to new directory", action="store_true")
parser.add_argument("-i", "--interactive", help="Run script in interactive mode", action="store_true")
args = parser.parse_args()
if len(sys.argv)==1:
# display help message when no args are passed.
parser.print_help()
sys.exit(1)