【问题标题】:Python going with argv or *arg?Python 与 argv 或 *arg 一起使用?
【发布时间】:2014-03-04 02:51:17
【问题描述】:

如果使用sys.argv,是否有任何理由使用*arg 或者sys.argv 能够做*arg 会做的所有事情?

例如:

>>>def test(*arg):
>>>    return arg
>>>
>>>print test('hello','salut','hola')
>>>('hello','salut','hola')

当我在从命令行调用的名为 trial.py 的文件中使用 sys.argv 时:

import sys
def test(argument):
    return argument

print test(sys.argv[1])


python trial.py 'hello','salut','hola'
hello,salut,hola

或者argv 是否真的适合只接收一个参数,argv 是否有可能拥有超过 2 个 items(argv[0],argv[1])

【问题讨论】:

  • 你混淆了两个完全不同的东西。对于初学者,*arg 不是变量。这是一个命令,意思是“解压变量arg的内容。你可以很容易地做到*foo*bar
  • @JoelCornett 我意识到我可以在这里使用 *anything 作为变量的名称,* 会解压它。我想知道的是,当使用 argv 时,它似乎也需要多个参数。
  • @tijko: sys.argv 不接受任何参数。这不是一个函数。它只是一个字符串列表。当您执行脚本时,python 会将脚本名称后面的所有命令行参数放入一个列表中。您可以像这样(如果需要)_, first_arg, second_arg = sys.argv 解压缩此列表,或者您可以将它们解压缩为函数的参数,例如test(*sys.argv).
  • @Joel Cornett 您对 sys.argv 的解释非常有帮助。我不认为它是`[script.py,第一,第二,第三]。如果您在下面阅读我的 cmets,我在引号和逗号中加上了使它成为一个长字符串:|

标签: python arguments argv


【解决方案1】:

sys.argv 是一个字符串列表,其中包含提供给脚本的任何可能的命令行参数。

第一个元素将是脚本本身的名称,其余条目将对应于通过命令行调用命令时指定的项目。所以要回答你的最后一个问题,argv 可以包含超过 2 个项目。

例如,如果您有一个名为 testme.py 的脚本并以

开头
testme.py this is a test

然后

sys.argv[0] would contain "test.me"
sys.argv[1] would contain "this"
sys.argv[2] would contain "is"
sys.argv[3] would contain "a"
sys.argv[4] would contain "test"

shell 将确定分配给 sys.argv 的条目 - 在您的情况下,因为它是 一个 连续字符串,没有空格分隔部分,它被认为是一个参数(因此似乎已连接)。

【讨论】:

  • 所以可以建立该列表以包括脚本本身和下一个条目之外的更多内容?我发现参数将被连接到一个字符串,用于 argv[1]。
  • 默认是“构建”的,是的。
  • 我不确定我是否理解这个问题,但参数没有连接,它们中的每一个都成为字符串列表中的一个单独条目(即sys.argv)。该列表会自动为您填充(构建),无需您执行任何操作(一旦您在命令行上提供参数),您可以访问信息。这回答了你的问题吗?
  • @Levon 好吧,我用逗号括号分隔每个参数,我得到一个长字符串。 'this','is','a' 将返回 this,is,a 所有连接。这就是我认为列表中只有两个项目而第二个项目只是串联的原因。
  • @tijko 看看帖子调用脚本的方式以及这个答案的方式。它们是两个不同的东西。 shell 规则定义了它如何分解参数。在这种情况下,由于 没有空格,它被 shell 解析为单个标记(或“参数”)。不同的 shell 行为会略有不同,Python 会在 windows 中玩游戏以使 cmd.exe “按预期工作”。
【解决方案2】:

sys.argv 是一个列表,其中包含在命令行上调用您的 python 脚本的所有参数,脚本本身被认为是“参数 0”。

它是一个普通变量,与任何其他恰好包含列表的变量相同。所以sys.argv*arg之间没有“选择”。 *arg 是用于解包列表(或其他序列)以作为多个参数传递给调用的语法。您可以在传递sys.argv 时使用此语法,就像使用任何其他包含列表的变量一样。或者您可以省略 * 并将整个列表作为一个参数传递。同样,列表是否恰好是 sys.argv 与发生的事情无关。

我认为您感到困惑的根源在于,您从中调用 Python 脚本的 shell 没有像 Python 那样考虑将多个参数分开。在 Python 中,您使用逗号分隔多个参数,因此 'hello','salut','hola' 将是 3 个参数(尽管在逗号后放置空格会更常见)。

在大多数 shell OTOH 中,参数由空格分隔。 'hello','salut','hola' 不包含任何空格,因此它只是 一个 参数。所以它作为一项显示在sys.argv 的 Python 列表中。没有什么神奇的事情可以为您将多个参数连接成一个。只是曾经只有一个论点。让 Python 级别的 sys.argv 拥有 3 个项目的方法是调用您的脚本,如下所示:

python trial.py 'hello' 'salut' 'hola'

看起来您在 shell 命令行中使用引号的方式就像在 Python 中一样。在大多数 shell 中,您并不总是需要引用字符串,因为一切都是字符串。相反,引号用于告诉 shell 包含空格的字符串实际上是一个包含空格的参数,而不是多个参数,或者禁用 shell 默认情况下在任何地方执行的某些特殊处理。

在 Python 中,'hello' 是使字符串“hello”所必需的,因此 Python 不会尝试将其读取为变量 hello。但在 shell 中,'hello'hello 都是相同的,只是表示字符串“hello”。但是也可以写he'll'o,只引用字符串的一部分。这只是改变了 shell 如何处理引号内的空格和其他特殊字符,但仍然产生相同的字符串“hello”。这就是为什么 shell 将您的表单 'hello','salut','hola' 解释为字符串“hello,salut,hola”。引号外没有空格,因此这 3 个单词不会被视为单独的参数,并且在完成告诉 shell 如何处理特殊字符的工作后,引号就会消失。

【讨论】:

  • 这是一个很棒的总结,真的一针见血。你知道为什么[hi, salut, hola] 有效,但(hi, salut, hola) 无效吗?
  • 取决于您使用它的环境。 [hi, salut, hola] 是 3 个项目的列表(假设变量已定义)。 (hi, salut, hola) 是一个包含 3 个项目的元组(除非它是一个调用,例如 some_func(hi, salut, hola),但它本身就是一个元组)。你可以用一个列表做很多事情,你也可以用一个元组做很多事情,但不是所有事情; [hi, salut, hola](hi, salut, hola) 不应该做同样的事情,你也不应该认为它们是一样的。
  • 我了解数据类型,它可以传递列表而不能传递元组的事实,以及传递括号字符而不是括号的事实。我为此做了一个单独的帖子,结果证明这是一个 BASH 的事情。括号是 BASH 运算符。
  • 哦,我明白了。我以为您的意思是您在 Python 中使用它们,而不是在 Bash 命令中调用 Python。这两种形式在 Bash 中都有点不寻常。您尝试将哪些实际参数值传递给脚本?
  • 这一切都源于我误解了它们的用法。因此,对于实际任务或需求没有太多的上下文,只是我在随机测试示例中尝试它们。我收到了一些回复,说这一切都很奇怪,我应该解释一下,我更多的是要弄清楚他们的能力是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-20
  • 2022-11-20
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多