Включить файлы модуля .pyd в сборку py2exe - PullRequest
2 голосов
/ 06 марта 2012

Я пытаюсь скомпилировать скрипт на 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

Я могу увидеть файл Scientific_numerics_package_id.pyd по адресу "C:\Python27\Lib\site-packages\Scientific\win32". Я хочу включить этот файл модуля в компиляцию. Я попытался скопировать вышеуказанный файл в папку "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 ]

3 голосов
/ 06 марта 2012

Py2exe позволяет вам указать дополнительные модули Python (как .py, так и .pyd) с помощью опции includes:

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

EDIT. Вышесказанное должно работать, если Python способен

import Scientific.win32.Scientific_numerics_package_id
1 голос
/ 10 марта 2012

Ошибка ImportError исправлена ​​с помощью предложений «Gil.I» и «Janne Karila» путем установки pythonpath и с помощью функции include.Но перед этим мне пришлось создать файл __init__.py в папке win32 обоих модулей.Кстати, я все еще получил еще одну ошибку для вышеуказанного скрипта - ссылка

1 голос
/ 06 марта 2012

Есть способ обойти эти типы проблем, которые я использовал несколько раз.Чтобы добавить дополнительные файлы к результату 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 ()

Так что правильное расширениеиспользуется.Возможно, вам придется немного коснуться кода, но это должно стать хорошей отправной точкой для того, что вам нужно.

1 голос
/ 06 марта 2012

Я столкнулся с подобной проблемой с py2exe , и единственное решение, которое я могу найти, - это использовать другой инструмент для преобразования python в exe - pyinstaller

Очень простой в использовании инструмент и, что важнее, он работает!

UPDATE

Как я понял из ваших комментариев ниже, запуск вашего скрипта из командной строки также не работает из-за ошибки импорта ( Моя рекомендация - сначала проверить ваш код из командной строки, а затем попытаться преобразовать его в EXE )

Похоже, проблема PYTHONPATH.
PYTHONPATH - это список путей (похожих на Windows PATH), которые программы python используют для поиска модулей импорта. Если ваш скрипт запускается из вашей IDE, это означает, что PYTHONPATH правильно установлен в IDE, поэтому все импортированные модули найдены.

Чтобы установить 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()
...