使用选项中的一些参数运行python脚本

2024-09-21 05:53:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经阅读了sys文档,但是有些东西我仍然不清楚。我已经在stackoverflow上寻找了一些类似的问题,但是我没有发现任何有用的问题(显然,任何参考都是值得赞赏的!)。

我想创建一个脚本,比如foo.py,其中我想从3个参数传递到6个参数:

$ python foo.py arg1 arg2 arg3

在任何情况下都必须给出前3个参数;如果未传递任何内容,则在具有默认参数值的函数中使用后3个参数。

问题是我该怎么做?到目前为止,我正在考虑编写如下foo.py(这是一个简单的示例集,只是为了有一些具体的东西来支持我的问题):

import sys

def example(credit_mom, credit_dad, debt_mom, debt_dad = 1000,
            salary = 2000, bonus = 0):
    total_gain = salary + credit_dad + credit_mom + bonus
    total_loss = debt_dad + debt_mom

    return total_gain - total_loss

if __name__ == '__main__':
    if len(sys.argv) < 4:
        sys.exit('Need at least 3 arguments. The order is as follows:\n\
            1.credit_mom;\n\
            2.credit_dad;\n\
            3.debt_mom;\n\
            4.others')
    else:
        sys.exit(example(sys.argv[1],
                         sys.argv[2],
                         sys.argv[3],
                         sys.argv[4],
                         sys.argv[5],
                         sys.argv[6]))

如果运行此脚本,显然会出现IndexError异常:

$ python foo.py 110 110 220
Traceback (most recent call last):
  File "foo.py", line 19, in <module>
    sys.argv[4],
IndexError: list index out of range

Tags: py脚本参数fooexamplesystotalgain
3条回答

使用Argparse

我建议你用argparse(和here is the tutorial)。省去了手动检查参数是否存在的麻烦。此外,argparse将--help参数作为freebie提供,它将读取为每个参数定义的help=""字符串(如果提供)。

示例程序

在您的例子中,有三个强制(位置)参数和三个可选参数。示例argparse代码如下所示:

#!/usr/bin/python
# coding: utf-8

import argparse

def parseArguments():
    # Create argument parser
    parser = argparse.ArgumentParser()

    # Positional mandatory arguments
    parser.add_argument("creditMom", help="Credit mom.", type=float)
    parser.add_argument("creditDad", help="Credit dad.", type=float)
    parser.add_argument("debtMom", help="Debt mom.", type=float)

    # Optional arguments
    parser.add_argument("-dD", "--debtDad", help="Debt dad.", type=float, default=1000.)
    parser.add_argument("-s", "--salary", help="Debt dad.", type=float, default=2000.)
    parser.add_argument("-b", "--bonus", help="Debt dad.", type=float, default=0.)

    # Print version
    parser.add_argument("--version", action="version", version='%(prog)s - Version 1.0')

    # Parse arguments
    args = parser.parse_args()

    return args

def example(credit_mom, credit_dad, debt_mom, debt_dad = 1000, salary = 2000, bonus = 0):
    total_gain = salary + credit_dad + credit_mom + bonus
    total_loss = debt_dad + debt_mom

    return total_gain - total_loss

if __name__ == '__main__':
    # Parse the arguments
    args = parseArguments()

    # Raw print arguments
    print("You are running the script with arguments: ")
    for a in args.__dict__:
        print(str(a) + ": " + str(args.__dict__[a]))

    # Run function
    print(example(args.creditMom, args.creditDad, args.debtMom, args.debtDad, args.salary, args.bonus))

除了使用argparse(我推荐使用),这可以通过切片和展开来解决:

    sys.exit(example(*sys.argv[1:7]))

切片将只包含实际存在的元素,即使没有足够的元素来满足请求的切片大小。

虽然我支持argparse方法,但这里有一个快速而肮脏的方法:

arg1, arg2, arg3 = [None, False, []]
if sys.argv[1:]:   # test if there are atleast 1 argument (beyond [0])
    arg1 = sys.argv[1]
    if sys.argv[2:]:
        arg2 = sys.argv[2]  # careful 'True' is a string, not a boolean
        arg3 = sys.argv[3:]  # rest

大多数情况下,当我开始向脚本中添加参数解析时,我都会使用它,而我对参数的选择还没有成熟。它更适合于“位置”而不是“选项”(使用argparse术语)。

相关问题 更多 >

    热门问题