【问题标题】:Python , getopt , how to get a listPython,getopt,如何获取列表
【发布时间】:2021-02-19 15:56:15
【问题描述】:

我正在尝试使用库 getopt 来捕获从命令行给出的路径列表,如下所示:

python script.py -l ["a","b","c","d","e"] -p 80 ....

我写的是这样的:

def getValue(self):
        ''' 
            get value from command line and initialize 
            variable !
        '''

        try:
            opts,args = getopt.getopt( self.args ,                                  
                                       "hl:us:r:p:" ,
                                       ['help','local_path','update',"remote_host","remote_path","parameter"])
        except getopt.GetoptError as err:
            print(str(err))
            self.usage()

## ----------------- SETTING VARIABLE PASSED BY COMMAND LINE ------------------ ##      

        for opt,arg in opts:
        #----------------------------------------------------------      
            if opt in ("-l","--local_path"):
                self.local_path = arg
                if DEBUG:   
                    print('local path: ',self.local_path)
        #-----------------------------------------------------------      
            elif opt in ("-h", "--help"):
                self.usage()
        #-----------------------------------------------------------      
            elif opt in ("-s", "--remote_host"):
                self.remote_host = arg
                if DEBUG:
                    print('Simulation host: ', self.remote_host)
        #-----------------------------------------------------------      
            elif opt in ("-r", "--remote_path"):
                self.remote_path = arg
                if DEBUG:
                    print('Simulation path: ', self.remote_path)
        #-----------------------------------------------------------      
            elif opt in ("-p", "--parameter"):
                self.parameter = arg
                if DEBUG:
                    print('Simulation parameter: ',self.parameter)
        #-----------------------------------------------------------
            elif opt in ("-u","--update"):
                #if self.remote_host and self.remote_path:
                    self.update()
        #-----------------------------------------------------------
            else:
                assert False, "Unhandled Option"
        #-----------------------------------------------------------

但不幸的是,这对每个 opts 只取一个值(-l,-p ....) 怎样才能达到我的目的? 提前谢谢!!

【问题讨论】:

  • 不要使用getopt;它主要是为了方便移植已经使用它的另一种语言的代码。对于新代码,请使用argparse
  • 如果您打算将-l 的单个参数作为列表文字,您需要先引用整个内容; [ 对 shell 有特殊的意义。 python script.py -l '["a", "b"]' 然后在您的代码中,您仍然需要使用 ast.literal_eval 将字符串解析为 Python 文字。

标签: python command-line-arguments


【解决方案1】:

我已经稍微简化了您的脚本,以专门解决您关于从命令行传递参数列表的问题。

您有一个选择是多次指定相同的标志以将多个参数发送到您的程序中。例如:

import getopt
import sys

opts, args = getopt.getopt(
    sys.argv[1:],
    'hl:p:',
    ['help', 'local_path', 'parameter'],
)

local_paths =  []
for opt, arg in opts:
    if opt in ('-l', '--local_path'):
        local_paths.append(arg)
        print(opt + ': ' + arg)
    if opt in ('-p', '--parameter'):
        print(opt + ': ' + arg)

print('local_paths: ' + str(local_paths))

如下使用:

$ python script.py -la -lb -p 80
-l: a
-l: b
-p: 80
local_paths: ['a', 'b']

另一个选项(如果您必须通过命令行将列表本身传递给标志的单个实例)是使用某种序列化。 JSON 可以胜任这项任务,但您也可以使用 csv 或其他。示例:

import getopt
import json
import sys

opts, args = getopt.getopt(
    sys.argv[1:],
    'hl:p:',
    ['help', 'local_path', 'parameter'],
)

for opt, arg in opts:
    if opt in ('-l', '--local_path'):
        list_arg = json.loads(arg)
        print(opt + ': ' + str(list_arg))
    if opt in ('-p', '--parameter'):
        print(opt + ': ' + arg)
$ python script.py -l '["a","b"]' -p 80
-l: ['a', 'b']
-p: 80

注意 -l 标志 ('["a","b"]') 后面的 JSON 引号 (')。这种表示法“保护”参数不被 bash 求值。

如果您像在示例中所做的那样传递参数,python 仍然会收到一个参数,但它并不像我认为的那样工作:

import getopt
import sys

opts, args = getopt.getopt(
    sys.argv[1:],
    'hl:',
    ['help', 'local_path'],
)

for opt, arg in opts:
    if opt in ('-l', '--local_path'):
        print(opt + ': ' + arg)
        print('type: ' + str(type(opt)))
$ python script.py -l ["a","b"]
-l: [a,b]
type: <class 'str'>

-l 标志的参数实际上是 python 中的字符串 "[a,b]"。发生这种情况是因为 bash 在运行脚本之前评估了表达式 ["a","b"],所以现在 python 中的反序列化有点棘手。可能值得避免这种方式并坚持使用标准的序列化模式。

the docs澄清上面的符号:

shortopts 是脚本要识别的选项字母字符串,选项需要参数后跟冒号(':')

所以hl: 表示我们接受-h-l,但-l 必须有一个参数,否则我们会得到类似:

getopt.GetoptError: option -l requires argument

【讨论】:

  • 我不明白 'hl:p:' 与参数的关系。你能解释一下吗?
  • 在上面的shortopts 上查看我的编辑。我还修正了一个错字以增加清晰度
猜你喜欢
  • 1970-01-01
  • 2013-09-27
  • 2020-08-31
  • 2013-12-07
  • 1970-01-01
  • 2017-07-08
  • 2020-08-15
  • 1970-01-01
相关资源
最近更新 更多