如何使用argparse或sys avrg在命令行中设置变量值

时间:2019-01-05 08:35:03

标签: python python-3.x

我正在尝试在我的python代码中使用argparse来基于命令行设置5个等于某些值的不同变量。如果未输入这些变量,它将被设置为默认值,该值已在我的代码中定义。 因此,如果我运行代码:

python test.py CSV = "/Home/data/file.csv" length = 1 cluster = 7 dim = 5 
fnumber = 8

它将设置CSV = "/Home/data/file.csv"length = 1cluster = 7dim = 5fnumber = 8

但是相反,我运行代码:

python test.py CSV = "/Home/data/file.csv" cluster = 7 fnumber = 8

它将设置CSV = "/Home/data/file.csv"length = 4cluster = 7dim = 9fnumber = 8,因为在我的代码中已经将长度预定义为7并且dim预先定义为9。

无论我在命令行中键入什么内容,都应替换下面代码中已经定义的值

困难的部分是我必须在命令行中键入类似“ length = 1”的字符串,而不仅仅是输入值1。这是因为我希望用户界面更清晰,因为可以保留一些变量如果我必须使用空格替换那些空参数,则为空白,它将看起来很糟糕。因此,我需要在命令行中输入变量值的声明

import argparse  
CSV = "Data/a1.csv"
length = 4           
cluster = 3
dim = 9
fnumber = 15

3 个答案:

答案 0 :(得分:1)

输入所有命令行参数,在等号(length=1而不是length = 1)之间不要留空格,因为它仍然是命令行约定。然后,遍历所有命令行参数并调用内置的Python函数exec(更多信息here)来设置所有配置变量。请注意,这应该在所有默认设置都设置好之后。

请注意,通常不建议使用exec,因为它将在输入中运行任何内容。如果您打算发布此代码,则应考虑为命令行参数创建过滤器。为此,首先将命令行参数的字符串除以等号,然后检查拆分的第一部分是否在您的可配置变量集中,第二部分是否实际上是数字(如果这就是您想要的数字)。

答案 1 :(得分:1)

这是一个简单的示例,显示了如何使用argparse来完成此操作,并允许您定义默认值。要使用它,您需要遵循其参数传递的约定/样式,该约定/样式在=周围没有空格,并且要求每个参数都以-(或--开头,请参阅文档。)

可能会很花哨,例如,允许以多种方式指定参数。对于该选项和许多其他选项,建议您参考该模块的documentation

请注意,parse_args()中传递的所示值是sys.argv中对于由所有连接在一起并用空格分隔的命令行组成的命令行的值。

import argparse


DEFAULT = dict(length=1, cluster=2, dim=3, fnumber=4)
parser = argparse.ArgumentParser(description='Test app')

parser.add_argument('-CSV', action="store")
parser.add_argument('-length', action="store", default=DEFAULT['length'])
parser.add_argument('-cluster', action="store", type=int, default=DEFAULT['cluster'])
parser.add_argument('-dim', action="store", type=int, default=DEFAULT['dim'])
parser.add_argument('-fnumber', action="store", type=int, default=DEFAULT['fnumber'])

args = parser.parse_args(['-CSV="/Home/data/file.csv"', '-length=1', '-cluster=7',
                          '-dim=5'])

print('args.CSV:', args.CSV)
print('args.length:', args.length)
print('args.cluster:', args.cluster)
print('args.dim:', args.dim)
print('args.fnumber:', args.fnumber)

print()
args2 = parser.parse_args(['-CSV="/Home/data/file2.csv"', '-cluster=42', '-fnumber=5'])
print('args2.CSV:', args2.CSV)
print('args2.length:', args2.length)
print('args2.cluster:', args2.cluster)
print('args2.dim:', args2.dim)
print('args2.fnumber:', args2.fnumber)

输出:

args.CSV: "/Home/data/file.csv"
args.length: 1
args.cluster: 7
args.dim: 5
args.fnumber: 4

args2.CSV: "/Home/data/file2.csv"
args2.length: 1
args2.cluster: 42
args2.dim: 3
args2.fnumber: 5

答案 2 :(得分:0)

尝试一下:

def parse_assign(args, keywords):
    """Parse args for keyword assignments.

    Arguments:
        args: List of arguments in the form of repeated 'foo = bar' assignments.
        keywords: List of keywords to look for.

    Returns:
        A dict of found keywords with their values.
    """
    rv = {}
    for word in keywords:
        try:
            rv[word] = args[args.index(word) + 2]
        except (IndexError, ValueError):
            pass
    return rv

说明:如果word不在args中,则index将生成ValueError样本。如果args.index(word) + 2大于args的长度,则会得到一个IndexError

在IPython中的测试:

In [15]: args                                                                                            
Out[15]: 
['CSV',
 '=',
 '"/Home/data/file.csv"',
 'length',
 '=',
 '1',
 'cluster',
 '=',
 '7',
 'dim',
 '=',
 '5',
 'fnumber',
 '=',
 '8']

In [16]: parse_assign(args, ['CSV', 'length', 'cluster', 'dim', 'fnumber'])                              
Out[16]: 
{'CSV': '"/Home/data/file.csv"',
 'length': '1',
 'cluster': '7',
 'dim': '5',
 'fnumber': '8'}

添加默认值会使它稍微复杂一些:

def parse_assign2(args, defaults):
    """Parse args for keyword assignments.

    Arguments:
        args: List of arguments in the form of repeated 'foo = bar' assignments.
        keywords: dict of defaults.

    Returns:
        A dict of found keywords with their values, merged with the defaults.
    """
    rv = {}
    keywords = defaults.keys()
    for word in keywords:
        try:
            rv[word] = args[args.index(word) + 2]
        except (IndexError, ValueError):
            pass
    return {**defaults, **rv}