9

我对 python 还很陌生,并且在使用命令行参数时我被困在如何构造我的简单脚本上。

该脚本的目的是自动化我工作中与排序和处理图像相关的一些日常任务。

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

这是我目前的结构。

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'
4

3 回答 3

8

如果没有设置选项,您可以append_const将 funcs 设置为属性,args.funcs然后使用一个 if 语句来提供默认行为:

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

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

% test.py -i -d
func2
func3

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


响应更新 2

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

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

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

    sys.exit将打印No jpegs foundstderr并以退出代码 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)
于 2013-01-16T13:19:39.203 回答
6

您可以通过检查 args 的数量是否等于 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)
于 2017-03-07T19:44:34.377 回答
4

那是你要的吗?

if args.list:
    func1()
if args.interactive:
    func2()
if args.dimensions:
    func3()
if not any(vars(args).values()):
    func1()
    func2()
    func3()

(感谢@JFSebastian 的any版本)

于 2013-01-16T12:46:12.243 回答