简体   繁体   English

从C应用程序导入Python脚本时,为什么需要在sys.path中显式添加os.getcwd()?

[英]Why do I need to explicitly add os.getcwd() to sys.path when importing Python scripts from a C application?

I was going through the Python documentation regarding Extending Python with C/C++ , and I found a very interesting scenario. 我浏览了有关使用C / C ++扩展Python的Python文档,发现了一个非常有趣的场景。 Consider that I have the following, trivial Python script named test_script.py in my working directory: 考虑一下我的工作目录中有以下名为test_script.py琐碎Python脚本:

import time
def My_Python_Func():
    print "My_Python_Func() Called: " + str(time.time())

In the same directory, I have a file called another_test_script.py , which has: 在同一目录中,我有一个名为another_test_script.py的文件,该文件具有:

import test_script
test_script.My_Python_Func()

Which works fine, when called as python ./another_test_script.py . 当被称为python ./another_test_script.py时,它工作正常。 Now, I'm trying to call said function from a C environment linked with the Python libraries as follows: 现在,我试图从与Python库链接的C环境中调用上述函数,如下所示:

#include <stdio.h>
#include <Python.h>

PyObject *pName, *pModule, *pDict, *pFunc, *pVal;

int main()
{
    const char* script_name = "test_script";
    const char* func_name   = "My_Python_Func";

    Py_Initialize();

    pName = PyString_FromString(script_name);

    PyRun_SimpleString("import os");
    PyRun_SimpleString("import sys");
    /* * * * IF I COMMENT THE FOLLOWING LINE OUT, pModule IS ALWAYS SET TO NULL * * * */
    PyRun_SimpleString("sys.path.insert(0, os.getcwd())");
    pModule = PyImport_Import(pName);

    Py_DECREF(pName);
    if (pModule != NULL)
    {
        pFunc = PyObject_GetAttrString(pModule, func_name);
    }
    pDict = PyModule_GetDict(pModule);
    pFunc = PyDict_GetItemString(pDict, func_name);
    if (PyCallable_Check(pFunc))
    {
        PyObject_CallObject(pFunc, NULL);
        Py_DECREF(pModule);
        Py_DECREF(pName);
    }
    else
    {
        PyErr_Print();
    }
    Py_Finalize();
    return 0;
}

As noted in the comments in the above C program, commenting out the line containing PyRun_SimpleString("sys.path.insert(0, os.getcwd())") causes the call to PyImport_Import to fail (returning NULL ). 如上述C程序中的注释所述,注释掉包含PyRun_SimpleString("sys.path.insert(0, os.getcwd())")会导致对PyImport_Import的调用失败(返回NULL )。 Furthermore, calling PyRun_SimpleString("import test_script") appears to behave the same way. 此外,调用PyRun_SimpleString("import test_script")行为似乎相同。

Why do I need to manually add the current working directory to Python's sys.path list of strings, when simply importing it from another Python script in the same working directory? 简单地从同一工作目录中的另一个Python脚本导入当前工作目录时,为什么需要将当前工作目录手动添加到Python的sys.path字符串列表中? Furthermore, why does Python not search the current working directory in the first place (as os.getcwd() returns the correct path)? 此外,为什么Python首先不搜索当前工作目录(因为os.getcwd()返回正确的路径)? Is this an appropriate solution, if I wish to import functions from scripts bundled with my C application? 如果我希望从与C应用程序捆绑在一起的脚本中导入函数,这是否是一个合适的解决方案?

Adding the script directory to sys.path is a peculiarity of the python executable; 将脚本目录添加到sys.pathpython可执行文件的特性; it is not done by default when the interpreter is initialized, since it is not always appropriate to do so in embedded applications. 初始化解释器时,默认情况下不执行此操作,因为在嵌入式应用程序中这样做并不总是合适的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM