【问题标题】:Use Python command line argument as function names and function values使用 Python 命令行参数作为函数名和函数值
【发布时间】:2015-07-03 11:06:48
【问题描述】:

与这个问题有关Command line arguments in python.

使用 SYS 模块,如何在我的代码中使用命令行参数作为函数名和函数值 - 而不导入其他模块?

我想要一个仅使用 sys.另外,请不要使用可变长度参数的答案。这些令人困惑。假设在命令行中只指定了函数名和一个函数变量。

import sys

def reversal(aaa): return aaa[::-1]

a = sys.argv[1]
b = sys.argv[2]

print a(b)

在命令行

cpu_location$ python blah.py reversal 'abcdefg'

Traceback (most recent call last):
File "blah.py", line 8, in <module>
print a(b)
TypeError: 'str' object is not callable

我想知道如何让 sys.argv[1] 被认为是一个函数名,从而调用我定义的函数。

我看到的其他帖子是以下内容的混搭: - 处理 C/C++ 并添加一些其他模块 - 根本不使用 sys - 使用 argv 项作为函数的值和其他文件的名称,而不是函数的名称

【问题讨论】:

标签: python-2.7 command-line-arguments


【解决方案1】:

eval 解决方案更好的是:

a = globals()[sys.argv[1]]
a(b)

globals() 返回一个将全局变量名称映射到这些全局变量的字典。所以globals()['reversal'] 计算为reversal 函数。

它比eval 函数更安全。使用您的方法,您可以执行以下操作:

python blah.py 'lambda x: x+"hi"' foobar

这将打印foobarhi,这是出乎意料的,因为这不是函数名。

【讨论】:

  • 我不明白。你的例子有什么问题?就我而言,第一个参数将始终是我在脚本本身中定义的函数。这就是为什么我希望它成为函数名。
  • @VISQL:这只是尽可能避免使用evalexec 的一般准则。它允许人们让脚本做他们想做的任何事情。使用这种方法,您可以将行为限制在您想要的范围内,即从函数名称中获取函数。
【解决方案2】:

2 小时后,我找到了答案。我认为以非常简单的方式在这里发布它是值得的。

Python 中基本上没有“函数”数据类型,但有人确实提到了一个内置的函数 evalExecute python commands passed as strings in command line using python -c(我自己的例子不需要-c)

解决办法,就是改变

a = sys.argv[1]

a = eval(sys.argv[1])

这将使传入的单词,反转,被评估。它将评估为一个函数。那么 a(b) 调用将是对字符串函数的完美调用,就像它的定义方式一样。输出如下:

cpu_location$ python blah.py reversal unquoted
detouqnu

cpu_location$ python blah.py reversal 'withquotes'
setouqhtiw

【讨论】:

  • 不要使用eval(),尤其是在没有清理输入的情况下。它所做的是将参数评估为 Python 代码,这是非常危险的。阅读this 了解更多信息。
  • 谢谢。文章现在在我头上。如果我构建更复杂的东西,我会记住这一点。这个项目只是为了我,练习。在命令行中测试我的简单函数比将我所有的测试放在脚本中并在我运行脚本时得到一个充满文本的屏幕更容易 - 每个函数都有输出。
  • (多年后)。我也习惯了这种sys.argv 方法来构建我自己的文件拆分器。它有位置参数,可以告诉它只将一个文件拆分为每个文件的x 行,或者以相同的方式拆分目录中的所有文件。这些参数是使用sys.argv 从命令行解析的。但是,在命令行传递的所有项目都没有被评估为函数。
【解决方案3】:

使用谷歌模块:火

pip install fire

这是一个简单的例子:

import fire

class Calculator(object):
  """A simple calculator class."""

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

然后,您可以从命令行运行:

python calculator.py double 10  # 20
python calculator.py double --number=15  # 30

【讨论】:

  • 不错的功能。在这种情况下,Calculator 只能被调用。回到我写这篇文章的时候,我打算在一个文件中包含多个不同名称的函数(不是 ant 类),我想从命令行调用这些函数。 argv + eval 用于此目的。作为第一个参数传递的任何名称都将被视为函数名称,随后的 args 作为该函数的参数。此外,我更喜欢通过内置的小示例完成,而不是非默认模块。
猜你喜欢
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
相关资源
最近更新 更多