在py2exe编译中包含.pyd模块文件

时间:2012-03-06 08:10:32

标签: python py2exe

我正在尝试编译python脚本。在执行exe时我得到了: -

C:\Python27\dist>visualn.exe
Traceback (most recent call last):
  File "visualn.py", line 19, in <module>
  File "MMTK\__init__.pyc", line 39, in <module>
  File "Scientific\Geometry\__init__.pyc", line 30, in <module>
  File "Scientific\Geometry\VectorModule.pyc", line 9, in <module>
  File "Scientific\N.pyc", line 1, in <module>
ImportError: No module named Scientific_numerics_package_id

我可以在位置"C:\Python27\Lib\site-packages\Scientific\win32"看到Scientific_numerics_package_id.pyd文件。我想将此模块文件包含在编译中。我试图在“dist”文件夹中复制上面的文件,但没有好处。有什么想法吗?

更新 这是脚本:

from MMTK import *
from MMTK.Proteins import Protein
from Scientific.Visualization import VRML2; visualization_module = VRML2
protein = Protein('3CLN.pdb')
center, inertia = protein.centerAndMomentOfInertia()
distance_away = 8.0
front_cam = visualization_module.Camera(position= [center[0],center[1],center[2]+distance_away],description="Front")
right_cam = visualization_module.Camera(position=[center[0]+distance_away,center[1],center[2]],orientation=(Vector(0, 1, 0),3.14159*0.5),description="Right")
back_cam = visualization_module.Camera(position=[center[0],center[1],center[2]-distance_away],orientation=(Vector(0, 1, 0),3.14159),description="Back")
left_cam = visualization_module.Camera(position=[center[0]-distance_away,center[1],center[2]],orientation=(Vector(0, 1, 0),3.14159*1.5),description="Left")
model_name = 'vdw'
graphics = protein.graphicsObjects(graphics_module = visualization_module,model=model_name)
visualization_module.Scene(graphics, cameras=[front_cam,right_cam,back_cam,left_cam]).view()

4 个答案:

答案 0 :(得分:3)

Py2exe允许您通过includes选项指定其他Python模块(.py和.pyd):

setup(
    ...
    options={"py2exe": {"includes": ["Scientific.win32.Scientific_numerics_package_id"]}}
)

EDIT。如果Python能够

,上述应该有效
import Scientific.win32.Scientific_numerics_package_id

答案 1 :(得分:1)

我遇到similar probelm with py2exe并且我能找到的唯一解决方案是使用另一个工具将python转换为exe - pyinstaller

它非常容易使用,更重要的是,它的工作原理!

<强>更新

正如我从下面的评论中所理解的那样,由于导入错误(我建议首先从命令行检查代码,然后尝试将其转换为EXE,因此从命令行运行脚本也不起作用)

看起来像PYTHONPATH问题 PYTHONPATH是python程序用来查找导入模块的路径列表(类似于Windows PATH)。 如果您的脚本从IDE运行,这意味着在IDE中正确设置了PYTHONPATH,因此找到了所有导入的模块。

要设置PYTHONPATH,您可以使用:

import sys|
sys.path.append(pathname)

或使用以下代码将路径参数下的所有文件夹添加到PYTHONPATH:

import os
import sys

def add_tree_to_pythonpath(path):
    """
    Function:       add_tree_to_pythonpath
    Description:      Go over each directory in path and add it to PYTHONPATH
    Parameters:     path - Parent path to start from
    Return:         None
    """    
    # Go over each directory and file in path
    for f in os.listdir(path):
        if f ==  ".bzr" or  f.lower() ==  "dll":
            # Ignore bzr and dll directories (optional to NOT include specific folders)
            continue
        pathname = os.path.join(path, f)
        if os.path.isdir(pathname) ==  True:
            # Add path to PYTHONPATH
            sys.path.append(pathname)

            # It is a directory, recurse into it
            add_tree_to_pythonpath(pathname)
        else:
            continue

def startup():
    """
    Function:       startup
    Description:      Startup actions needed before call to main function 
    Parameters:     None
    Return:         None
    """    

    parent_path = os.path.normpath(os.path.join(os.getcwd(), ".."))
    parent_path = os.path.normpath(os.path.join(parent_path, ".."))

    # Go over each directory in parent_path and add it to PYTHONPATH
    add_tree_to_pythonpath(parent_path)

    # Start the program
    main()

startup()

答案 2 :(得分:1)

有一种方法可以解决我多次使用的这类问题。为了将额外的文件添加到py2exe结果,您可以扩展媒体收集器以获得它的自定义版本。以下代码是一个示例:

import glob
from py2exe.build_exe import py2exe as build_exe

def get_py2exe_extension():
    """Return an extension class of py2exe."""

    class MediaCollector(build_exe):
        """Extension that copies  Scientific_numerics_package_id missing data."""

        def _add_module_data(self, module_name):
            """Add the data from a given path."""
            # Create the media subdir where the
            # Python files are collected.
            media = module_name.replace('.', os.path.sep)
            full = os.path.join(self.collect_dir, media)
            if not os.path.exists(full):
               self.mkpath(full)

            # Copy the media files to the collection dir.
            # Also add the copied file to the list of compiled
            # files so it will be included in zipfile.
            module = __import__(module_name, None, None, [''])
            for path in module.__path__:
                for f in glob.glob(path + '/*'):  # does not like os.path.sep
                    log.info('Copying file %s', f)
                    name = os.path.basename(f)
                    if not os.path.isdir(f):
                        self.copy_file(f, os.path.join(full, name))
                        self.compiled_files.append(os.path.join(media, name))
                    else:
                        self.copy_tree(f, os.path.join(full, name))

        def copy_extensions(self, extensions):
            """Copy the missing extensions."""
            build_exe.copy_extensions(self, extensions)
            for module in ['Scientific_numerics_package_id',]:
                self._add_module_data(module)

    return MediaCollector

我不确定哪个是Scientific_numerics_package_id模块,所以我假设您可以像这样导入它。复制扩展方法将获得您遇到问题的不同模块名称,并将所有数据复制到dir文件夹中。一旦你有了这个,为了使用新的媒体收藏家,你只需要做以下的事情:

cmdclass ['py2exe'] = get_py2exe_extension()

以便使用正确的扩展名。您可能需要稍微触摸一下代码,但这应该是您需要的良好起点。

答案 3 :(得分:1)

通过设置pythonpath和使用include函数,使用“Gil.I”和“Janne Karila”建议来纠正ImportError。但在此之前,我必须在两个模块的win32文件夹中创建__init__.py文件。 顺便说一下,上面的脚本仍然有另一个错误 - link