如何将列表和其他值作为命令行参数传递?

时间:2013-01-22 15:41:25

标签: python python-2.7

我想将4个参数传递给我的python脚本,其中一个必须是一个列表。即使它只包含1个元素。

参数的顺序无关紧要。

    import sys
    print sys.argv

    one = sys.argv[1]
    two = sys.argv[2]
    three = sys.argv[3]
    four = sys.argv[4]

    print "one: " + one
    print "two: " + two
    print "three: "+ three
    print "four: " + four

这就是我所说的。

    python myScript.py name file setting ['listItem1']

第四项是具有一个元素的列表。但是,当我打印它时,我看到了

    four: [listItem1]

我想看看

    four: ['listItem1']

4 个答案:

答案 0 :(得分:6)

也许更好的方法是调用你的脚本

python myScript.py name file setting listItem1 ...

然后使用切片:

four = sys.argv[4:]

这使得python语法不受shell限制,这很难看,并且可能会在shell中使用特殊字符导致更多麻烦。

更好的方法是使用argparse模块实现正确的CLI。

答案 1 :(得分:2)

正如PersonArtPhoto指出的那样,你需要转义qutoation标记以防止shell自己使用它们。

你要在程序中最终得到的是一个类似于列表的字符串,这不是你想要的

import sys 

four = sys.argv[4]
print four[2]

显示

$ python myscript.py one two three [\'first\',\'second\']
f

'f'来自索引"['first','second']",因为它只是一串字符


使python解释的一种方法是eval,但非常气馁,因为它非常不安全eval将字符串解释为代码,因此不应在用户输入上使用它,因为用户可以输入任何并且python将执行它。

import sys 

four = eval(sys.argv[4])
print four[1]

显示

$ python myscript.py one two three [\'first\',\'second\']
second

相反,我建议采用更安全的方法。使用命令行标志表示您正在发送参数列表

import sys

# make sure the --args flag was passed
if '--args' not in sys.argv:
    print >> sys.stderr, 'Please pass the "--args" flag followed by a list of'\
            ' arguments'
    sys.exit(1) #terminate execution if it wasn't

four = sys.argv[sys.argv.index('--args')+1:] # everything passed after --args
print four

显示

$ python myscript.py one two three --args 'first' 'second'
['first', 'second']

如果你知道列表前总会有三个args,你可以简单地使用一个切片

import sys

one, two, three = sys.argv[1:4] # grab indicies 1, 2, and 3
four = sys.argv[4:]
print one
print two
print three
print four

显示

$ python myscript.py one two three 'first' 'second'
one
two
three
['first', 'second']

答案 2 :(得分:1)

您需要转义引号

python myScript.py name file setting [\'listItem1\']

答案 3 :(得分:1)

<强>程序:

import sys, ast, getopt, types

def main(argv):            
    arg_dict={}
    switches={'li':list,'di':dict,'tu':tuple}
    singles=''.join([x[0]+':' for x in switches])
    long_form=[x+'=' for x in switches]
    d={x[0]+':':'--'+x for x in switches}
    try:            
        opts, args = getopt.getopt(argv, singles, long_form)
    except getopt.GetoptError:          
        print "bad arg"                       
        sys.exit(2)       

    for opt, arg in opts:        
        if opt[1]+':' in d: o=d[opt[1]+':'][2:]
        elif opt in d.values(): o=opt[2:]
        else: o =''
        print opt, arg,o
        if o and arg:
            arg_dict[o]=ast.literal_eval(arg)

        if not o or not isinstance(arg_dict[o], switches[o]):    
            print opt, arg, " Error: bad arg"
            sys.exit(2)                 

    for e in arg_dict:
        print e, arg_dict[e], type(arg_dict[e])        

if __name__ == '__main__':
    main(sys.argv[1:])        

命令行:

python py.py --l='[1,2,3,[1,2,3]]' -d "{1:'one',2:'two',3:'three'}" --tu='(1,2,3)'

<强>输出:

args:  ['--l=[1,2,3,[1,2,3]]', '-d', "{1:'one',2:'two',3:'three'}", '--tu=(1,2,3)']
tu (1, 2, 3) <type 'tuple'>
di {1: 'one', 2: 'two', 3: 'three'} <type 'dict'>
li [1, 2, 3, [1, 2, 3]] <type 'list'>

此代码段将采用-l--li=之类的短或长命令切换,并在切换到像list,tuple或dict之类的Python数据结构后解析文本。解析的数据结构最终在具有长格式切换键的字典中。

使用ast.literal_eval相对安全。它只能解析python数据定义。