python argparse: 'Namespace' 错误

1 投票
2 回答
4415 浏览
提问于 2025-05-11 02:25

我正在尝试创建一个处理流程,这个流程有一些解析选项,其中有些是必须的,有些是可选的。

我在下面的代码中遇到了一个问题:

    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 个回答

0

这个错误是在执行 (options, args) = ... 这个赋值时出现的。解析器返回了一个对象,叫做 argparse.Namespace。但是这个赋值试图把它分成两个部分,比如说:

(options, args) = (args[0], args[1])

不过,Namespace 类并没有实现像列表或元组那样的分割功能。理论上,我们可以自定义一个 Namespace 类来实现这个功能。

这就是错误背后的技术细节。实际的问题是 argparseoptparse 的工作方式不同。

argparse 的文档最后提到:

把 (options, args) = parser.parse_args() 替换成 args = parser.parse_args(),并为位置参数添加额外的 ArgumentParser.add_argument() 调用。请记住,之前称为 options 的,现在在 argparse 中被称为 args。

optparse 会处理所有带标记的字符串,并把它们的值放在一个 options 对象里(我忘了具体是什么样的对象)。它无法处理的字符串会作为第二个返回值以列表的形式返回。

argparse 要求你定义所有的参数,包括带标记的(称为“可选参数”)和不带标记的(称为“位置参数”)。所以在 optparse 中出现在 args 列表里的值,在 argparsenamespace 中会以它们自己的“名称/目标”出现。

还有一种调用 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 是一个函数,用来把输入的字符串转换成其他类型。intfloat 是最常见的替代类型。str 可以用,因为它什么都不做——返回的还是它接收到的字符串。实际上,argparse 使用了一个身份函数作为默认的 type(例如 lambda x:x)。

4

parse_args 这个函数其实只返回一个东西,而不是两个。

args = parser.parse_args()

撰写回答