Python sys.argv列表和索引

29
在下面的代码中,我知道sys.argv使用列表,但是我不清楚这里如何使用索引。
def main():

  if len(sys.argv) >= 2:
    name = sys.argv[1]
  else:
    name = 'World'
  print 'Hello', name

if __name__ == '__main__':
  main()
如果我改变了 <\p>标签。
name = sys.argv[1]
to
name = sys.argv[0] 

并为参数输入一些内容,它将返回:

Hello C:\Documents and Settings\fred\My Documents\Downloads\google-python-exercises
\google-python-exercises\hello.py

这种说法有点道理。

有人能解释一下这里的“2”是怎么用的吗:

if len(sys.argv) >= 2:

这里的1是如何使用的:

name = sys.argv[1] 
5个回答

48

假设你在命令行中有:

C:\> C:\Documents and Settings\fred\My Documents\Downloads\google-python-exercises
\google-python-exercises\hello.py John

为了更容易阅读,让我们把它简化为:

C:\> hello.py John

argv 表示通过命令行输入的所有项目,但计数从零(0)开始,而不是从一(1)开始:在这种情况下,“hello.py” 是元素 0,“John” 是元素 1。

换句话说,sys.argv[0] == 'hello.py'sys.argv[1] == 'John' ... 但是看看,这里有多少个元素?2,对吧!因此,即使数字是0和1,在这里仍然有2个元素。

len(sys.argv) >= 2 只是检查您是否输入了至少两个元素。在这种情况下,我们刚好输入了两个元素。

现在让我们将您的代码翻译成英语:

define main() function:
    if there are at least 2 elements on the cmd-line:
        set 'name' to the second element located at index 1, e.g., John
    otherwise there is only 1 element... the program name, e.g., hello.py:
        set 'name' to "World" (since we did not get any useful user input)
    display 'Hello' followed by whatever i assigned to 'name'

那么这意味着什么?这意味着如果您输入:

  • "hello.py",代码输出 "Hello World",因为您没有提供名称
  • "hello.py John",代码输出 "Hello John",因为您提供了一个名称
  • "hello.py John Paul",代码仍然输出 "Hello John",因为它不保存也不使用 sys.argv[2],即 "Paul" -- 您能看到在这种情况下 len(sys.argv) == 3 吗?因为在 sys.argv 列表中有3个元素。

1
你好!我看到其他人已经回答得很好了,但我想提供一种更注重代码的纯英语翻译,如果有这样的东西的话。谢谢! - wescpy
如果您需要知道位置和值,您也可以启动循环 for i in range(1, len(sys.argv)-1): 然后使用 sys.argv[i] 获取您的值。 - Jesse Chisholm
虽然你可以这样做,但使用"len()-1"在Python中并不是典型的,尽管它在其他语言中是一种常见模式;如果需要索引和值,则更符合Python惯用法的是使用enumerate()。此评论也没有回答OP的问题,即如何使用索引--他们没有询问如何查询特定值或其位置。 - wescpy

12

sys.argv是传递给Python程序的参数列表。第一个参数sys.argv[0]实际上是调用程序的名称。这不是Python的特性,而是大多数操作系统的工作方式。sys.argv[0]存在的原因是为了让您可以根据程序的调用方式来更改程序的行为。sys.argv[1]是您实际传递给程序的第一个参数。

由于Python中的列表(像大多数序列一样)从0开始索引,并且在列表末尾索引超出范围会导致错误,因此在访问sys.argv [1]之前需要检查列表是否具有长度大于等于2的值。


6
简而言之,sys.argv 是一个包含在运行程序时出现的单词列表。列表的第一个单词(即列表的第一个元素)是程序的名称,而列表的其余元素是任何提供的参数。在大多数计算机语言(包括Python)中,列表从零开始索引,这意味着列表中的第一个元素(在本例中为程序名称)是 sys.argv [0],第二个元素(如果有)是第一个参数,即 sys.argv [1] 等等。
测试 len(sys.argv) >= 2 只是简单地检查列表是否具有长度大于或等于2,如果提供了至少一个参数,则会满足此条件。

1
你似乎在几个地方把“array”用来表示“list”。它们是不同的东西。正如你在第一句话中提到的那样,sys.argv是一个列表。 - Thomas Wouters
谢谢,知道第一个元素是程序名称对于帮助理解这个问题有很大的帮助! - Fred Gerbig
@Thomas:好观点,我会修复的... 我倾向于交替使用这些术语,因为Python的列表通常与C的数组具有相同的功能(在这种情况下,区别并不特别重要)。 - David Z

5

如果我想返回名字和姓氏,例如:Hello Fred Gerbig,我会使用下面的代码。虽然这段代码有效,但它是否是最正确的方法呢?

import sys
def main():
  if len(sys.argv) >= 2:
    fname = sys.argv[1]
    lname = sys.argv[2]
  else:
    name = 'World'
  print 'Hello', fname, lname
if __name__ == '__main__':
  main()

编辑:发现上面的代码在使用两个参数时有效,但在使用一个参数时会崩溃。尝试将len设置为3,但没有效果,仍然会崩溃(重新阅读其他回答后现在明白了为什么3没用)。如果只输入一个参数,如何绕过参数?或者如何进行错误检查,返回“您必须输入2个参数”?

编辑2:问题已解决:

import sys
def main():
  if len(sys.argv) >= 2:
    name = sys.argv[1] + " " + sys.argv[2]
  else:
    name = 'World'
  print 'Hello', name
if __name__ == '__main__':
  main()

是的,您第一个版本的崩溃可能是因为使用了未定义的标签fname和lname。 - Van Gale
我不清楚未定义标签...它们与名称标签有什么不同?名称不也是未定义的吗? - Fred Gerbig
在第一个版本中,如果命令行参数少于2个,打印语句将会出错,因为'fname'和'lname'未被定义(即在赋值之前使用)。 - Van Gale
没有参数时,我会得到以下错误:print 'Hello',fname,lname UnboundLocalError:在赋值之前引用了本地变量'fname'有一个参数时,我会得到以下错误:lname = sys.argv [2] IndexError:列表索引超出范围我想我明白了...需要回到书本上看看,相信很快就能理解。 - Fred Gerbig

2

如前面不同的答案所解释的那样,sys.argv 包含调用您的 Python 脚本的命令行参数。

然而,Python 提供了帮助您轻松解析命令行参数的库。即,新的标准 argparse。使用 argparse 将免去您编写大量样板代码的需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接