【问题标题】:How to call python method that expects CLI arguments?如何调用需要 CLI 参数的 python 方法?
【发布时间】:2019-01-02 18:04:00
【问题描述】:

真的不知道该怎么表达这个, 但是我正在将 bash 脚本转换为 python,并且我试图调用通常通过 CLI 调用的 python 库中的方法。该方法使用 argparse 并在调用时需要 2 个参数。

我不确定如何调用此方法并在从单独的 python 脚本调用它时提供两个参数。

我尝试过的:

>>  from somelibrary import mymethod as method
>>  method.main('foo', 'bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: main() takes 0 positional arguments 
but 2 were given

>>> method.main()
usage: [-h] foo bar
: error: the following arguments are required: 
foo, bar

非常感谢任何帮助!

【问题讨论】:

  • 看看mymethod 的样子会很有帮助
  • 您是否有理由不通过 subprocess 模块将模块作为 CLI 命令运行?大概main 没有返回任何用处,所以subprocess.run([sys.executable, '-m', 'somelibrary', 'foo', 'bar']) 似乎是直接的解决方案......
  • 您要调用的对象是什么?你控制它吗?你能改变它来接受论点吗?您确定在将此代码用作库时没有更合适的入口点吗?
  • @user2357112 我实际上是在调用一个接受两个参数的方法:一个 sqlite 文件和一个 tsv 文件。它将使用 tsv 文件的内容填充 sqlite 数据库。我不控制它。我也不相信我能改变它。
  • @user2357112 更新!我和它的主人谈过了,我可以把它改成接受 args。我会这样做

标签: python command-line-interface argparse


【解决方案1】:

该函数几乎可以肯定地调用了没有 Python 参数的 Argparser.parse_args() 方法:

parser.parse_args()

这从sys.argv list 中获取参数,获取除第一个元素之外的所有元素。

sys.argv只是一个列表,你可以自己设置:

import sys
from somelibrary import mymethod as method

sys.argv[1:] = ['foo', 'bar']
method()

如果您可以更改该项目或建议更改,最好(要求)更新main() 函数以获取参数:

def main(args=None):
    if args is None:
        args = sys.argv[1:]

    # ...

    parser.parse_args(args)

您可能需要考虑脚本并非旨在导入另一个程序的可能性(它可能会改变程序其他部分所依赖的全局状态,或者它可能以 sys.exit() 结尾并因此关闭您的程序除非您专门捕获了 SystemExit 异常。将脚本作为子进程运行可能会更容易,使用:

import sys
import subprocess

result = subprocess.run([sys.executable, '/path/to/somelibrary', 'foo', 'bar'])

【讨论】:

  • 我很想听听我的回答没有帮助或错误的地方,值得一票否决。这样我可以改进我的答案!
  • 感谢 Martijn Pieters!我选择了这个作为最佳答案,因为我最终获得了修改 main 以接受参数的权限。
【解决方案2】:

使用 sys.argv - 它包含传递给 py 脚本的参数。

from somelibrary import mymethod as method
>>> sys.argv[1:] = ['foo', 'bar']
>>> method.main()

【讨论】:

  • 这假定sys.argv 中还没有任何其他参数。替换内容,而不是extending,可能更可靠。
  • @ShadowRanger OP 正在测试解释器中的代码 - 我很肯定它没有更多参数
  • $ ipython3 --classic, &gt;&gt;&gt; sys.argv 产生 ['/path/to/ipython3', '--classic']。即使没有,交互式解释器也经常被用来测试你以后想在脚本中使用的东西。您编辑的新方法在一般情况下更安全。
  • 太棒了,这行得通!但是,当我实现它时,它将从 django 中的 celery 任务中调用。不确定这是否会彻底改变现状?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多