没有提供参数时python argparse设置行为 [英] python argparse set behaviour when no arguments provided

查看:67
本文介绍了没有提供参数时python argparse设置行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对python还是很陌生,在使用命令行参数时,我对如何构造简单的脚本一无所知.

I'm fairly new to python and I'm stuck on how to structure my simple script when using command line arguments.

该脚本的目的是使我的工作中与图像分类和处理有关的一些日常任务自动化.

The purpose of the script is to automate some daily tasks in my job relating to sorting and manipulating images.

我可以指定参数并让它们调用相关函数,但是我也想在没有提供参数时设置默认操作.

I can specify the arguments and get them to call the relevant functions, but i also want to set a default action when no arguments are supplied.

这是我当前的结构.

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()

但是当我不提供任何参数时,将不会调用任何东西.

But when I supply no arguments nothing will be called.

Namespace(dimensions=False, interactive=False, list=False)

如果没有论据,我想要的是一些默认行为

What i want is some default behaviour if no arguements are supplied

if args.list:
        func1()
    if args.interactive:
        func2()
    if args.dimensions:
        func3()
    if no args supplied:
        func1()
        func2()
        func3()

这似乎应该很容易实现,但是我迷失了如何检测所有参数是否为假,而无需遍历参数并测试所有是否为假的逻辑.

This seems like it should be fairly easy to achieve but I'm lost on the logic of how to detect all arguments are false without looping through the arguments and testing if all are false.

多个参数一起有效,这就是为什么我没有遵循Elif的方法.

Multiple arguments are valid together, that is why I didn't go down the elif route.

这是我更新的代码,其中考虑了@unutbu的答案

Here is my updated code taking into account the answer from @unutbu

这似乎并不理想,因为所有内容都包裹在if语句中,但短期内我找不到更好的解决方案.我很高兴接受@unutbu的回答,我们将对您提供的任何其他改进表示赞赏.

it doesn't seem ideal as everything is wrapped in an if statement but in the short term i couldn't find a better solution. I'm happy to accept the answer from @unutbu, any other improvements offered would be appreciated.

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'

推荐答案

如果未设置任何选项,则可以将函数append_const用作属性args.funcs,然后使用一个if语句提供默认行为:

You could append_const the funcs to an attribute, args.funcs, and then use one if-statement to supply the default behavior if no options are set:

if not args.funcs:
    args.funcs = [func1, func2, func3]


import argparse

def func1(): pass
def func2(): pass
def func3(): pass

parser = argparse.ArgumentParser()
parser.add_argument(
    "-l", "--list",
    dest='funcs', action="append_const", const=func1,
    help="Create CSV of images", )
parser.add_argument(
    "-i", "--interactive",
    dest='funcs', action="append_const", const=func2,
    help="Run script in interactive mode",)
parser.add_argument(
    "-d", "--dimensions",
    dest='funcs', action='append_const', const=func3,
    help="Copy images with incorrect dimensions to new directory")
args = parser.parse_args()
if not args.funcs:
    args.funcs = [func1, func2, func3]

for func in args.funcs:
    print(func.func_name)
    func()


% test.py
func1
func2
func3

% test.py -d
func3

% test.py -d -i
func3
func2

请注意,与您的原始代码不同,这使用户可以控制函数的调用顺序:

Note that, unlike your original code, this allows the user to control the order the functions are called:

% test.py -i -d
func2
func3

这可能是可取的,也可能是不可取的.

That may or may not be desireable.

为响应更新2 :

您的代码可以正常工作.但是,这是您可以进行组织的另一种方式:

Your code will work just fine. However, here is another way you could organize it:

  • 您可以将主程序嵌套在if子句中,而不是 使用

  • Instead of nesting the main program inside an if clause, you could use

if not lists:
    sys.exit('No jpegs found')
# put main program here, unnested

sys.exit No jpegs found打印到stderr并以退出代码1终止.

sys.exit will print No jpegs found to stderr and terminate with exit code 1.

尽管我最初建议使用functools.partial,但现在想到的是另一种-也许更简单的方法:代替

Although I originally suggested using functools.partial, another -- perhaps simpler -- way now comes to mind: Instead of

for func in args.funcs:
    func()

我们可以说

for func, args in args.funcs:
    func(args)

我们要做的就是在args.func中存储一个元组(func, args) 而不是单独的功能.

All we need to do is store a tuple (func, args) in args.func instead of the function alone.

例如:

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)

这篇关于没有提供参数时python argparse设置行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆