我很好奇使用 argparse 时幕后发生了什么。我检查过 here 和 here ,显然命名空间目前only exists in the argparse library .
可能我使用了错误的关键字来搜索 SO/Google。也有可能我问的是一个毫无意义或显而易见的问题,但我们开始吧。
当通过 argparse 在 Python 中捕获输入字符串时:
>python palindrome.py 'Taco cat!?'
运行下面的代码时,我希望通过指定 parser.add_argument('string'... 生成的命名空间充当单个输入字符串的缓冲区。
我将字符串分配给“args”的下一行必须是我们第一次实际解析输入,产生与输入字符串的长度成比例的工作量。此时,“args”实际上包含一个 Namespace 对象,无法通过 for 循环或其他方式(据我所知)对其进行解析。
最后,为了使用“for”或其他一些循环来解析输入,我使用命名空间对象来填充字符串。我很好奇此过程会产生多少次与原始字符串长度成比例的计算时间?
这些步骤中的哪些是在幕后按地址复制还是按值复制?看起来乐观的最坏情况是 2 倍。一次创建 Namespace 对象,然后再次将其内容分配给“arg_str”
#! /usr/bin/env python
import sys
import argparse
parser = argparse.ArgumentParser(description='Enter string to see if it\'s a palindrome.')
parser.add_argument('string', help="string to be tested for palindromedness..ishness")
args = parser.parse_args()
arg_str = args.string
# I can parse by using 'for i in arg_str:' but if I try to parse 'for i in args:'
# I get TypeError: "Namespace' object is not iterable
感谢观看!!
最佳答案
操作系统(或 shell)首先解析命令行,将字符串传递给 Python 解释器,您可以在其中以 sys.argv
数组的形式访问它们。
python palindrome.py 'Taco cat!?'
成为
['palindrome.py', 'Taco cat!?']
parser.parse_args()
处理这些字符串,通常只是传递引用。当一个基本参数被“解析”时,该字符串被“存储”在命名空间中,带有 setattr(Namespace, dest, value)
,在您的示例中等同于 setattr(namespace , '字符串', sys.argv[1])
。
argparse.Namespace
没有什么特别之处。它是 Object
的一个简单子(monad)类。参数是简单的对象属性。 argparse
使用 setattr
和 getattr
访问这些,尽管用户通常可以使用 dot
格式(args .string
).它不做任何特殊的字符串处理。这完全是 Python 的责任。
命名空间不是可迭代的,也就是说,它不是列表或元组或类似的东西。它是一个对象。可以使用 vars(args)
(在 argparse 文档中)将命名空间转换为字典。因此,您可以使用 keys
和 items
遍历该字典。
还有一点。不要用 is
测试你的 arg.string
。使用 ==
或 in []
将其与其他字符串进行比较。这是因为通过 sys.argv
创建的字符串与通过 x = 'test'
创建的字符串不具有相同的 id
。要了解原因,请尝试:
argv = 'one two three'.split()
print argv[0]=='one' # true
print argv[0] is 'one' # false
print argv[0] in ['one', 'two','three'] # true
x = 'one'
print x is 'one' # true
print id(x)
print id('one')
print id(argv[0])
在可能的情况下,Python 会保留字符串的唯一副本。但如果字符串以不同的方式生成,它们将具有不同的 id,并且不满足 is
测试。
关于python - Python 如何从 argparse 填充字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20084718/