python argparse: 'Namespace' 错误
我正在尝试创建一个处理流程,这个流程有一些解析选项,其中有些是必须的,有些是可选的。
我在下面的代码中遇到了一个问题:
bandlist=[1,2,3,4,5,6,7,8]
process=['rad', 'ref', 'radref']
sensors=['LC', 'LO', 'LE', 'LT']
series=['4', '5', '7', '8']
usage = "usage: %prog [options] "
parser = argparse.ArgumentParser(usage=usage)
parser.add_argument('-d', '--directory', dest='directory', action='store', type=str, \
help='complete path of landsat product folder: mydir/filename/')
parser.add_argument('-p', '--process', dest='operation', action='store', choices = process, \
help='process requested: radiance, reflectance, both', default='rad')
parser.add_argument('-l', '--series', dest='satellite', action='store', choices = series , \
help='Landsat series:4, 5, 7, 8')
parser.add_argument('-s', '--sensor', dest='sensor', action='store', choices = sensors, \
help='sensor acronymous, for example LO for Landsat OLI, or LE for Landsat ETM+, etc..', default=None)
parser.add_argument('-o', '--output', dest='output', type=str, \
help='Directory of output raster. \n \
Unless specified, output directory will be workDirectory/results/datafolder/. \n \
If specified, the output directory wil be mydirectory/results/filename/rad (and/or ref)/', default=None)
parser.add_argument('-x', action='store_true', dest='bool', help='activate iterative radiance and/or reflectance computation for all the bands', default=False)
parser.add_argument('-b', '--bands', dest='bands', choices = bandlist, type=int, \
help='bands to process', nargs='*', default=None)
(options, args) = parser.parse_args()
然后出现了以下错误:
Traceback (most recent call last):
File "C:\Users\lbernardi\Desktop\extract\LandsatTMroutine_RadiometricCorrection_1.0.py", line 1210, in <module>
main()
File "C:\Users\lbernardi\Desktop\extract\LandsatTMroutine_RadiometricCorrection_1.0.py", line 784, in main
(options, args) = parser.parse_args()
TypeError: 'Namespace' object is not iterable
我不太明白这个错误是什么意思。感谢你的帮助!
相关文章:
- 暂无相关问题
2 个回答
这个错误是在执行 (options, args) = ...
这个赋值时出现的。解析器返回了一个对象,叫做 argparse.Namespace
。但是这个赋值试图把它分成两个部分,比如说:
(options, args) = (args[0], args[1])
不过,Namespace
类并没有实现像列表或元组那样的分割功能。理论上,我们可以自定义一个 Namespace 类来实现这个功能。
这就是错误背后的技术细节。实际的问题是 argparse
和 optparse
的工作方式不同。
在 argparse
的文档最后提到:
把 (options, args) = parser.parse_args() 替换成 args = parser.parse_args(),并为位置参数添加额外的 ArgumentParser.add_argument() 调用。请记住,之前称为 options 的,现在在 argparse 中被称为 args。
optparse
会处理所有带标记的字符串,并把它们的值放在一个 options
对象里(我忘了具体是什么样的对象)。它无法处理的字符串会作为第二个返回值以列表的形式返回。
argparse
要求你定义所有的参数,包括带标记的(称为“可选参数”)和不带标记的(称为“位置参数”)。所以在 optparse
中出现在 args
列表里的值,在 argparse
的 namespace
中会以它们自己的“名称/目标”出现。
还有一种调用 argparse 解析器的方法,叫做 parser.parse_known_args
,它的行为更像 optparse
。它无法处理的字符串会被放在一个 extras
列表中。
你提到有些参数是必需的,有些则不是。乍一看,你的代码把所有参数都设为“可选”。也就是说,如果你在命令行中没有包含相关的标记,这个参数就会使用默认值。
你有一个参数使用了 nargs='*'
。如果没有指定,默认值会是 None
或 []
(我忘了具体细节)。
你还可以指定 required=True
参数,这样一个“可选”参数就变成了必需的。抱歉让你感到困惑。在这种情况下,如果你在命令行中没有提供标记,解析器会抛出错误。
我没有仔细看你之前关于 optparse
的问题,看看你是否期望在 args
变量中有值。在 argparse
的用法中,那些是“位置参数”,是必需的(除非它们的 nargs
使它们变为“可选”)。
所以,虽然简单的解决办法是直接使用 args = parser.parse_args()
,但我怀疑还有更多的细节需要注意。
一个风格建议:
parser.add_argument('-d', '--directory', dest='directory', action='store', type=str, \
help='complete path of t product folder: mydir/filename/')
可以简化为
parser.add_argument('-d', '--directory', \
help='complete path of landsat product folder: mydir/filename/')
如果没有给定 dest
,它会从第一个长标记字符串推断出来。store
是默认的 action
值,str
是默认的 type
。
在 argparse
中,type
是一个函数,用来把输入的字符串转换成其他类型。int
和 float
是最常见的替代类型。str
可以用,因为它什么都不做——返回的还是它接收到的字符串。实际上,argparse
使用了一个身份函数作为默认的 type
(例如 lambda x:x
)。
parse_args
这个函数其实只返回一个东西,而不是两个。
args = parser.parse_args()