【问题标题】:Run a python script with arguments运行带有参数的 python 脚本
【发布时间】:2012-08-21 22:51:35
【问题描述】:

我想从 C 调用 Python 脚本,并传递脚本中需要的一些参数。

我要使用的脚本是mrsync,或者multicast remote sync。我从命令行得到了这个工作,通过调用:

python mrsync.py -m /tmp/targets.list -s /tmp/sourcedata -t /tmp/targetdata

-m 是包含目标 IP 地址的列表。 -s 是包含要同步的文件的目录。 -t 是目标机器上将放置文件的目录。

到目前为止,我设法通过使用以下 C 程序运行了一个不带参数的 Python 脚本:

Py_Initialize();
FILE* file = fopen("/tmp/myfile.py", "r");
PyRun_SimpleFile(file, "/tmp/myfile.py");
Py_Finalize();

这很好用。但是,我找不到如何将这些参数传递给 PyRun_SimpleFile(..) 方法。

【问题讨论】:

    标签: python c eclipse


    【解决方案1】:

    您似乎正在使用 Python.h 中的 Python 开发 API 寻找答案。这是一个应该可以工作的示例:

    #My python script called mypy.py
    import sys
    
    if len(sys.argv) != 2:
      sys.exit("Not enough args")
    ca_one = str(sys.argv[1])
    ca_two = str(sys.argv[2])
    
    print "My command line args are " + ca_one + " and " + ca_two
    

    然后是传递这些参数的 C 代码:

    //My code file
    #include <stdio.h>
    #include <python2.7/Python.h>
    
    void main()
    {
        FILE* file;
        int argc;
        char * argv[3];
    
        argc = 3;
        argv[0] = "mypy.py";
        argv[1] = "-m";
        argv[2] = "/tmp/targets.list";
    
        Py_SetProgramName(argv[0]);
        Py_Initialize();
        PySys_SetArgv(argc, argv);
        file = fopen("mypy.py","r");
        PyRun_SimpleFile(file, "mypy.py");
        Py_Finalize();
    
        return;
    }
    

    如果您可以将参数传递到您的 C 函数中,这项任务会变得更加容易:

    void main(int argc, char *argv[])
    {
        FILE* file;
    
        Py_SetProgramName(argv[0]);
        Py_Initialize();
        PySys_SetArgv(argc, argv);
        file = fopen("mypy.py","r");
        PyRun_SimpleFile(file, "mypy.py");
        Py_Finalize();
    
        return;
    }
    

    你可以直接通过。现在我的解决方案出于时间原因只使用了 2 个命令行参数,但是您可以对需要传递的所有 6 个参数使用相同的概念......当然还有更简洁的方法来捕获 python 端的参数,但是这只是基本的想法。

    希望对你有帮助!

    【讨论】:

    • 请注意,在 Python 3 中,您必须首先转换为宽字符 (wchar_t)。为此尝试 mbstowcs_s (#include )。
    • 嗨@Mike,你能看看这种情况,我需要将参数传递给python包应用程序(不仅仅是一个py文件):stackoverflow.com/questions/21036106/…
    • @JayZ - 抱歉,今天刚回来,看起来您在其他链接上得到了答案,但如果您需要更多帮助,请告诉我。
    • 我重温了这个例子——虽然 CPython 似乎也使用了argc,但我仍然会在自构建的argv 的末尾使用NULL 指针,就像在标准中一样Cargv.
    • @Mike 将“-m”选项放在哪里?如何在 Python/C api 中设置标志?
    【解决方案2】:

    你有两个选择。

    1. 打电话

      system("python mrsync.py -m /tmp/targets.list -s /tmp/sourcedata -t /tmp/targetdata")
      

      在您的 C 代码中。

    2. 实际使用mrsync(希望)定义的API。这更灵活,但更复杂。第一步是弄清楚如何将上述操作作为 Python 函数调用执行。如果mrsync 写得很好,就会有一个函数mrsync.sync(比如说)你称之为

      mrsync.sync("/tmp/targets.list", "/tmp/sourcedata", "/tmp/targetdata")
      

      一旦确定了如何执行此操作,您就可以使用 Python API 从 C 代码中直接调用该函数。

    【讨论】:

    • +1 您的第一种方法确实有效,谢谢。但是,我仍然很想知道是否无法使用我在第一篇文章中描述的 Python 解释器来实现。不幸的是,您的第二种方法在这种情况下不起作用,因为 mrsync 不提供 API。
    • 其实可以用 argv 初始化解释器,然后让它执行一个文件。不过,你得试试看,我不知道。
    • 选项 1 仅适用于“python”保证在系统路径中的假设
    • 使用系统功能总是得到我的反对。提供给系统的字符串受 shell 解释的影响,因此该函数非常危险。在 POSIX 系统中从 C 执行命令的正确方法是 exec* 函数。因此: execlp("python", "python", "mrsync.py", "-m", ..., "/tmp/targetdata", NULL);如果要链接到特定的 python 解释器,可以使用 Mike 的答案。但是请注意,如果您更新 python,您的应用程序将更容易崩溃,而仅使用 exec 时不一定是这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    相关资源
    最近更新 更多