在Python中将列表作为命令行参数指定

23

我正在使用getopt处理命令行可选参数,该参数应该接受一个列表。类似于这样:

foo.py --my_list=[1, 2, 3, 4,5] 

但是这会截断"[1,"之后的所有内容。

我的问题是: A) 有没有办法指定一个列表而不将其转换为字符串?(使用 getopt)

B) 如果我要将列表转换为字符串,如何将此列表转换为字符串?例如,类似于 mylist.split("?") 来摆脱方括号?是否有更好的方法?

谢谢

6个回答

29

我能想到两种选择:

  • 使用optparse,并使用append操作指定你想要的操作,如:foo.py --my_list=1 --my_list=2 ...
  • 将您的命令行指定为foo.py --my_list='1,2,3,4,5',然后使用x.split(',') 将值获取到列表中。您可以使用getoptoptparse来实现此方法。

第一种方法的优点是直接得到列表中的整数值,代价是命令行更长(但如果需要,可以为--my_list添加单字符选项)。 第二个优点是命令行较短,但在split()之后,你需要将字符串值'1''2'等转换为整数(也很容易)。


4
由于这篇文章已经发布 5 年,因此现在应使用 argparse 替代 optparse。 - SAAD
“使用附加操作”是什么意思?听起来很有趣,但不确定你在说什么。 - Monica Heddneck
@MonicaHeddneck 请参考 https://docs.python.org/3/library/optparse.html#standard-option-actions - 这里有一个 "append" 操作的示例:parser.add_option("-t", "--tracks", action="append", type="int") - Alok Singhal
请看一下我的答案,因为这个已经过时了,不是做这件事的首选方式。 - Nick

14
如果我不能在我的应用程序中使用标准解析器(optparse或argparse),那么我会使用ast.literal_eval函数来解析类型为list的输入参数,具体如下:
import sys, ast

inputList = ast.literal_eval( sys.argv[1] )
print type( inputList )
print inputList

假设这段代码存储在testParser.py文件中。通过执行脚本:
$ python testParser.py  "[1,2,3,4, [123, 456, 789], 'asdasd']"

我们得到以下输出:
<type 'list'>
[1, 2, 3, 4, [123, 456, 789], 'asdasd']

所以,使用足够安全的ast.literal_eval函数并将列表作为代码字符串插入,我们就可以得到理想的结果。
有用的链接: 使用Python的eval()与ast.literal_eval()?

http://docs.python.org/2/library/functions.html?highlight=eval#eval


7
也许你只需要在参数周围加上引号?
foo.py "--my_list=[1, 2, 3, 4,5]"

否则每个空格都会被视为参数的分隔符。

3
这不是因为Python的原因,而是由于Shell解析参数并将它们提供给Python程序。 - extraneon
1
部分正确。在Windows上,命令行只是一个字符串。即使UNIX也没有任何特殊的数据结构将参数传递给程序,它仍然只是一个字符串。但是,这是一种广泛实施的约定,但并非普遍存在。是的,C运行时有相关规范。 - Joey
1
你也可以使用 --my-list="[1, 2, 3, 4,5]"。我通常使用这种形式,因为它通常是像 --my-list="$MY_LIST" 这样的东西。 - Mike DeSimone
啊,我已经想了很多了,但不太熟悉 getopt,不知道那样行不行。 - Joey

6

一种更新的方法是使用argparse库,并将列表作为命令行参数添加。这样,您就不必手动解析。

示例:

parser = argparse.ArgumentParser()
parser.add_argument(
        "-values",
        nargs="*",  # expects ≥ 0 arguments
        type=int,
        default=[35, 40, 50, 60, 70, 80, 90],  # default list if no arg value
    )

您可以这样调用它:
python3 someprogram.py -values 1 2 3

截至2020年4月,这仍然是一种有效的方法。 - Nick

1

来自Python optparse帮助页面:

parser.add_option("-f")
parser.add_option("-p", type="float", nargs=3, dest="point")

当它解析命令行时

-f foo.txt -p 1 -3.5 4 -fbar.txt

optparse会设置

options.f = "foo.txt"
options.point = (1.0, -3.5, 4.0)
options.f = "bar.txt"

"


0

我被重定向到了重复的问题:
如何通过命令行将数组传递给Python - Stack Overflow

我正在回答这个问题:
命令行参数是字符串,它们不像程序中的文字那样解析。
argv会自动将命令行参数(由空格分隔)构造成一个列表,简而言之, sys.argv是一个列表。

    from sys import argv
    cmd = "arr = {sys.argv[1]}".format(argv)
    exec(cmd)
    print(arr[2])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接