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

查看:19
本文介绍了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 funcs 到一个属性,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

这可能是也可能不是.

响应更新 2:

您的代码可以正常工作.但是,您可以通过以下另一种方式组织它:

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

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

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

sys.exit 将打印 No jpegsfoundstderr 并以退出代码 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天全站免登陆