当前位置: 首页 > 面试题库 >

Py_Initialize运行需要哪些文件?

朱兴安
2023-03-14
问题内容

我正在研究一个简单的代码,该代码从C / C ++应用程序运行Python函数。为了做到这一点,我设置了PYTHONPATH并运行初始化,如下所示:

Py_SetPythonHome("../Python27");
Py_InitializeEx(0);

然后,导入模块并运行函数。效果很好。

我现在正在尝试为我的同事构建一个安装程序以运行我的代码。出于明显的原因,我想减少需要在此安装程序中包含的文件数量。

仔细研究这个主题会告诉我,我应该能够包含文件“ Python27.lib”和“ Python27.dll”,然后压缩“ DLL”和“
Lib”文件夹并将其包含在内。但是,当我尝试这样做时,Py_Initialize失败。

快速查看导致此失败的原因的结果表明,Py_Initialize似乎取决于Lib文件夹中的许多.pyc文件,包括(但不限于 warnings.pyc
__abcoll.pyc_ , __future_.pyc_ 和“编码”的内容”文件夹。

我不明白为什么会这样。有什么建议吗?


问题答案:

在开始的时候,我想说的话,有没有需要的模块(至少没有 非内置 之一) Py_InitializeEx ,所以是唯一的要求
python27.dll (顺便说一句: python27.lib不是* 必须的,除非你的同事要链接的东西反对它-但要使用
PythonInclude dir并不是一件容易的事。我有以下代码( 顺便说一句 :我正在使用通过 VStudio _ 10_ ( 2010 )构建的 Python 2.7.10 ): _
*_ __

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

int main() {
    int i = 0;
    char *pyCode = 
        "s = \"abc\"\n"
        "print s, 1234";
    Py_InitializeEx(0);
    i = PyRun_SimpleString(pyCode);
    Py_Finalize();
    printf("PyRun_SimpleString returned: %d\nPress a key to exit...\n", i);
    _getch();
    return 0;
}

它运行良好,可以从 VStudio 和命令行运行(将 .dll 复制到其文件夹中)。但是后来我将 .exe.dll
复制到另一台计算机上,当运行时, 砰!

ImportError: No module named site

考虑到:

  • 我在运行 .exe 的两台计算机上的两个控制台中都没有设置 PYTHON * env vars (结果不同) __
  • 在两台机器上, Python 安装都在同一路径上(我以前(几年前)在无法运行的机器上对其进行了修改)

我不知道为什么它的行为不一样(我没有检查过的一件事是机器上可能存在某些注册表项可以工作?)。

注意站点 是( .py(c) )模块,位于 %PYTHON_INSTALL_DIR%\ Lib下

然后,我浏览了 Python 的源代码,然后遇到了这个(文件: pythonrun.c ,行: 269 ,函数
Py_InitializeEx pythonrun.c:269:Py_InitializeEx- 这就是我要引用源中的点的方式码):

    if (!Py_NoSiteFlag)
        initsite(); /* Module site */

而在 pythonrun.c:727中:initsite

    m = PyImport_ImportModule("site");

这很明显( Py_NoSiteFlag 为0)。

然后,我注意到 Py_NoSiteFlag 声明为extern __declspec(dllexport)([MS.Docs]:使用extern指定链接,[MS.Docs]:dllexport,dllimport),所以我将代码修改为:

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

extern __declspec(dllimport) int Py_NoSiteFlag;

int main() {
    int i = 0;
    char *pyCode = 
        "s = \"abc\"\n"
        "print s, 1234";
    Py_NoSiteFlag = 1;
    Py_InitializeEx(0);
    i = PyRun_SimpleString(pyCode);
    Py_Finalize();
    printf("PyRun_SimpleString returned: %d\nPress a key to exit...\n", i);
    _getch();
    return 0;
}

而且有效!好极了!

因此,在这一点上只需要 .dll 即可运行一段代码。但是我想您的代码要比它复杂一点(它具有 import s([Python
2.Docs]:import语句)。要解决 导入
问题,可以使用以下漂亮的模块:[Python 2 .docs]:modulefinder-
查找脚本使用的模块( Python 2.7 的标准模块的一部分)。

  • 将您从 C 执行的代码保存在 .py 文件中
  • 对它运行 modulefinder

这是我的代码的示例(我的 C 程序中的 pyCode 内容,保存在文件中)。 __

code.py

s = "abc"
print s, 1234

运行:

%PYTHON_INSTALL_DIR%\python -m modulefinder code.py

产量:

Name                      File
----                      ----
m __main__                code.py

但是 ,如果我import os在文件中添加一个(这是一个非常常见的模块)语句,则上面的命令将产生:

Name                        File
----                        ----
m StringIO                  %PYTHON_INSTALL_DIR%\lib\StringIO.py
m UserDict                  %PYTHON_INSTALL_DIR%\lib\UserDict.py
m __builtin__
m __future__                %PYTHON_INSTALL_DIR%\lib\__future__.py
m __main__                  a.py
m _abcoll                   %PYTHON_INSTALL_DIR%\lib\_abcoll.py
m _codecs
m _collections
m _functools
m _hashlib                  %PYTHON_INSTALL_DIR%\DLLs\_hashlib.pyd
m _heapq
m _io
m _locale
m _random
m _sre
m _struct
m _subprocess
m _threading_local          %PYTHON_INSTALL_DIR%\lib\_threading_local.py
m _warnings
m _weakref
m _weakrefset               %PYTHON_INSTALL_DIR%\lib\_weakrefset.py
m abc                       %PYTHON_INSTALL_DIR%\lib\abc.py
m array
m atexit                    %PYTHON_INSTALL_DIR%\lib\atexit.py
m bdb                       %PYTHON_INSTALL_DIR%\lib\bdb.py
m binascii
m cPickle
m cStringIO
m cmd                       %PYTHON_INSTALL_DIR%\lib\cmd.py
m codecs                    %PYTHON_INSTALL_DIR%\lib\codecs.py
m collections               %PYTHON_INSTALL_DIR%\lib\collections.py
m copy                      %PYTHON_INSTALL_DIR%\lib\copy.py
m copy_reg                  %PYTHON_INSTALL_DIR%\lib\copy_reg.py
m difflib                   %PYTHON_INSTALL_DIR%\lib\difflib.py
m dis                       %PYTHON_INSTALL_DIR%\lib\dis.py
m doctest                   %PYTHON_INSTALL_DIR%\lib\doctest.py
m dummy_thread              %PYTHON_INSTALL_DIR%\lib\dummy_thread.py
P encodings

%PYTHON_INSTALL_DIR%\lib\encodings__init__.py
m encodings.aliases
%PYTHON_INSTALL_DIR%\lib\encodings\aliases.py
m errno
m exceptions
m fnmatch %PYTHON_INSTALL_DIR%\lib\fnmatch.py
m functools %PYTHON_INSTALL_DIR%\lib\functools.py
m gc
m genericpath %PYTHON_INSTALL_DIR%\lib\genericpath.py
m getopt %PYTHON_INSTALL_DIR%\lib\getopt.py
m gettext %PYTHON_INSTALL_DIR%\lib\gettext.py
m hashlib %PYTHON_INSTALL_DIR%\lib\hashlib.py
m heapq %PYTHON_INSTALL_DIR%\lib\heapq.py
m imp
m inspect %PYTHON_INSTALL_DIR%\lib\inspect.py
m io %PYTHON_INSTALL_DIR%\lib\io.py
m itertools
m keyword %PYTHON_INSTALL_DIR%\lib\keyword.py
m linecache %PYTHON_INSTALL_DIR%\lib\linecache.py
m locale %PYTHON_INSTALL_DIR%\lib\locale.py
P logging %PYTHON_INSTALL_DIR%\lib\logging__init__.py
m marshal
m math
m msvcrt
m nt
m ntpath %PYTHON_INSTALL_DIR%\lib\ntpath.py
m opcode %PYTHON_INSTALL_DIR%\lib\opcode.py
m operator
m optparse %PYTHON_INSTALL_DIR%\lib\optparse.py
m os %PYTHON_INSTALL_DIR%\lib\os.py
m os2emxpath %PYTHON_INSTALL_DIR%\lib\os2emxpath.py
m pdb %PYTHON_INSTALL_DIR%\lib\pdb.py
m pickle %PYTHON_INSTALL_DIR%\lib\pickle.py
m posixpath %PYTHON_INSTALL_DIR%\lib\posixpath.py
m pprint %PYTHON_INSTALL_DIR%\lib\pprint.py
m random %PYTHON_INSTALL_DIR%\lib\random.py
m re %PYTHON_INSTALL_DIR%\lib\re.py
m repr %PYTHON_INSTALL_DIR%\lib\repr.py
m select %PYTHON_INSTALL_DIR%\DLLs\select.pyd
m shlex %PYTHON_INSTALL_DIR%\lib\shlex.py
m signal
m sre_compile %PYTHON_INSTALL_DIR%\lib\sre_compile.py
m sre_constants %PYTHON_INSTALL_DIR%\lib\sre_constants.py
m sre_parse %PYTHON_INSTALL_DIR%\lib\sre_parse.py
m stat %PYTHON_INSTALL_DIR%\lib\stat.py
m string %PYTHON_INSTALL_DIR%\lib\string.py
m strop
m struct %PYTHON_INSTALL_DIR%\lib\struct.py
m subprocess %PYTHON_INSTALL_DIR%\lib\subprocess.py
m sys
m tempfile %PYTHON_INSTALL_DIR%\lib\tempfile.py
m textwrap %PYTHON_INSTALL_DIR%\lib\textwrap.py
m thread
m threading %PYTHON_INSTALL_DIR%\lib\threading.py
m time
m token %PYTHON_INSTALL_DIR%\lib\token.py
m tokenize %PYTHON_INSTALL_DIR%\lib\tokenize.py
m traceback %PYTHON_INSTALL_DIR%\lib\traceback.py
m types %PYTHON_INSTALL_DIR%\lib\types.py
P unittest
%PYTHON_INSTALL_DIR%\lib\unittest__init__.py
m unittest.case %PYTHON_INSTALL_DIR%\lib\unittest\case.py
m unittest.loader %PYTHON_INSTALL_DIR%\lib\unittest\loader.py
m unittest.main %PYTHON_INSTALL_DIR%\lib\unittest\main.py
m unittest.result %PYTHON_INSTALL_DIR%\lib\unittest\result.py
m unittest.runner %PYTHON_INSTALL_DIR%\lib\unittest\runner.py
m unittest.signals %PYTHON_INSTALL_DIR%\lib\unittest\signals.py
m unittest.suite %PYTHON_INSTALL_DIR%\lib\unittest\suite.py
m unittest.util %PYTHON_INSTALL_DIR%\lib\unittest\util.py
m warnings %PYTHON_INSTALL_DIR%\lib\warnings.py
m weakref %PYTHON_INSTALL_DIR%\lib\weakref.py

Missing modules:
? _emx_link imported from os
? ce imported from os
? fcntl imported from subprocess, tempfile
? org.python.core imported from copy, pickle
? os.path imported from os, shlex
? os2 imported from os
? posix imported from os
? pwd imported from posixpath
? readline imported from cmd, pdb
? riscos imported from os
? riscosenviron imported from os
? riscospath imported from os

如您所见,有很多模块(我稍微修改了输出内容,而不是放置 %PYTHON_INSTALL_DIR% env var的实际路径)。为了使 Python
代码正常工作,您必须在安装程序中包括所有这些模块/软件包。

*关于 modulefinder 的输出的 *注释 (在使用它时我已经注意到):

  • 它以递归方式搜索模块,因此这是整个模块依赖关系树
  • 它搜索位于函数中的 导入 语句(因此,不仅限于模块级别的 导入 语句)
  • 搜索动态 import (例如[Python 2.Docs]: importname [,globals [,locals [,fromlist [,level]]]] ))

因此,查看 os 所需的模块,我不确定从 C中 取出 站点 导入是否有很大的区别。 __

重要提示 :为了确保您的 .exe文件 的任何计算机上的作品,你可能会考虑包括 VStudio C运行时库VCRTLib
msvcr ##(#)DLL。
:[MS.Docs]:运行时库参考)(其中
小号是安装程序中数字的占位符-表示 VStudio 版本)。



 类似资料:
  • 我们已经在现有的HDP上安装了nifi(HDF服务)。安装是成功的,我可以运行nifi没有任何错误。但我在PutHDFS中遇到了一个问题 我也附上了截图。

  • 问题内容: 我从“ 简单步骤中的Hibernate 3.2 ”一书开始学习Hibernate框架,但是我下载了最新版本的Hibernate,即4.1.9。根据这本书,我们需要在类路径中添加许多基本的jar,例如 Anttr-2.7.6.jar asm.jar asm-attrs.jar cglib-2.1.3.jar commons-collections-2.1.1.jar commons-lo

  • 我正在使用Cucumber插件在Eclipse中运行特性文件。我正在尝试使用标记来选择要运行的方案。 在我的特性文件中,我使用如下所示的不同标记标记了两个场景:

  • 问题内容: 假设我有一个由 用户 组成的预订数据库: 和他们的 票 及相关 航班 要移动此Google AppEngine,我需要更改什么? 我了解AppEngine 不允许加入 。 这是否意味着我的桌子应该成为所有领域的一大障碍? 预订 : 换句话说,我所有的查询现在都在同一个表上运行吗? 问题答案: 您需要进行哪些更改,主要取决于您需要运行哪些查询,而不取决于所拥有的数据。最有可能的是,您只需

  • 本文向大家介绍前端需要注意哪些SEO?相关面试题,主要包含被问及前端需要注意哪些SEO?时的应答技巧和注意事项,需要的朋友参考一下 合理的title,description,keyswords 搜索引擎对这三项的权重逐个减小,title 值强调重点即可,重要的关键 词出现不要超过两次,而且要靠前。 2 、不同页面的tilte要有所不同;description把页面的内容高度概括,长度合适,不可过分