pyinstaller, похоже, не находит файл данных

Изменить 3: я заменил __file__ на sys.argv[0], когда мне нужно знать местоположение моего скрипта / исполняемого файла. Это не совсем то же самое, но в моем случае, похоже, все работает нормально (по крайней мере, в исполняемой версии ...). Теперь все работает нормально, в однофайловом режиме, с использованием функции принятого ответа для доступа к файлам ресурсов!


Изменить 2: как показано в комментариях к принятому ответу, проблема связана с разрешением пути в моем сценарии; Я пытаюсь использовать __file__, чтобы получить местоположение сценария, чтобы получить доступ к его файлам ресурсов. Это не работает после упаковки, так как __file__ вернет имя файла из Python.dll в сценарий, поэтому всегда не будет пути, а будет просто имя файла. Поэтому мне нужно найти еще один прием, чтобы получить доступ к файлам ресурсов; временный обходной путь - переместить текущий каталог на путь к исполняемому файлу.

Кстати, это означает, что ConfigParser должен сообщать о проблеме при доступе к файлу, а не о том, что раздел отсутствует.

Я обновлю этот вопрос, указав, как я решил этот вопрос о разрешении пути.


У меня проблемы с pyinstaller, и, поскольку я использую его впервые, я уверен, что сделал что-то не так.

Итак, вот проблема: pyisntaller без проблем работает с написанным мной сценарием и генерирует кое-что в папке dist. Хорошо, теперь я хочу выполнить его, чтобы посмотреть, все ли прошло хорошо, и вот что я получаю:

C:\Program Files\PyInstaller\pyinstaller-1.5.1>p_tool\dist\p_tool\p_tool.exe -?
Traceback (most recent call last):
  File "<string>", line 104, in <module>
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 76, in f
ileConfig
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 112, in
_create_formatters
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/ConfigParser", line 532, in ge
t
ConfigParser.NoSectionError: No section: 'formatters'

Моя первая идея заключалась в том, что файл logging.conf отсутствовал, поэтому я добавил его (и некоторые другие файлы ресурсов) в файл p_tool.spec, но это не лучше.

Версия Python: 2.6.6, под WinXP. Я использую pyinstaller, так как он мне понадобится для упаковки файлов для рабочей станции Solaris.

Итак, у кого-нибудь была эта проблема? Единственная связанная тема - это следующий вопрос: Проблема PyInstaller, очень близка к моей проблеме, но безнадежно не получила ответа .


Edit3: сведения о ведении журнала удалены, поскольку на самом деле не связаны с проблемой.


person Joël    schedule 20.10.2011    source источник
comment
это кажется лучшим решением: stackoverflow.com/questions/404744/   -  person Gonzo    schedule 08.09.2012
comment
Правильно, спасибо за ссылку!   -  person Joël    schedule 28.11.2013


Ответы (3)


Во-первых, было бы разумно сделать print config_file / os.path.exists (config_file) перед его чтением, чтобы вы могли быть уверены, где находится файл и сможет ли python его найти.

Что касается фактического доступа к нему, os.path.split(__file__) выглядит почти правильно, но я не уверен, что он правильно работает под pyinstaller - правильный способ упаковки файлов - добавить их в файл .spec, pyinstaller затем загрузит их во время компиляции и распакует. в $ _MEIPASS2 / во время выполнения. Чтобы получить каталог _MEIPASS2 в упакованном режиме и использовать локальный каталог в распакованном (разработке) режиме, я использую это:

def resource_path(relative):
    return os.path.join(
        os.environ.get(
            "_MEIPASS2",
            os.path.abspath(".")
        ),
        relative
    )


# in development
>>> resource_path("logging.conf")
"/home/shish/src/my_app/logging.conf"

# in deployment
>>> resource_path("logging.conf")
"/tmp/_MEI34121/logging.conf"
person Shish    schedule 25.10.2011
comment
Этот ответ полон хороших советов. Итак, сначала печать пути, который я ищу, показывает, что __file__ разрешается как сценарий относительно Python.dll, что означает, что в моем случае os.path.split(...)[0] всегда пусто. Иначе говоря, это как если бы мой сценарий был локальным для любого места, где он вызывается ... Итак, теперь я должен найти другой способ доступа к моим файлам ресурсов. : - / - person Joël; 25.10.2011
comment
Чтобы завершить предыдущий комментарий: если я перейду в папку с исполняемым файлом перед его запуском, разрешение пути в порядке, и теперь инструмент запускается правильно! Итак, теперь я должен понять, как определить разрешение пути внутри моего кода Python, чтобы он работал, и это другая тема. Насчет resource_path функции, она наверняка пригодится, когда я попробую однофайловую упаковку. Итак, ваш ответ стоит награды! Спасибо за вашу помощь :-) - person Joël; 25.10.2011
comment
МЕЙПАСС или МЕЙПАСС2? Откуда я знаю? - person dranxo; 06.11.2013

Сообщение об ошибке ConfigParser.NoSectionError: No section: 'formatters' предполагает, что это не отсутствующий файл, а файл с отсутствующим разделом, который вам следует искать.

person Tavis Rudd    schedule 24.10.2011
comment
Я обновил вопрос, но сомневаюсь, что это действительно проблема из-за этого файла, поскольку версия Python работает без проблем. Так что я думаю, что это больше проблема с доступом к файлу. - person Joël; 24.10.2011

У меня была аналогичная проблема, но пока я не мог найти элегантного решения. `` Хак '', который я использовал, который помог мне, скажем, мой проект находится в '~/project/project_root', сначала в файле .spec:

excluded_sources = TOC([x for x in a.pure if not x[0].startswith('project_root')])

Здесь a - объект Analysis, в основном я удаляю все файлы своих проектов из PYZ, поэтому импорт туда не передается и относительные пути регистратора не будут вычисляться оттуда. После этого создайте объект Tree из проекта.

my_project_tree = Tree('~/project')

Затем добавьте это Tree в список TOC, который передается в COLLECT, так что:

COLLECT( exe,
           a.binaries,
           a.zipfiles,
           a.datas,
           my_project_tree,
           ....)

Папка вашего проекта должна быть добавлена ​​в папку dist. Проблема в том, что вы в конечном итоге тоже будете распространять pyc-файлы своего проекта, но пока не могли найти лучшего способа. Очень заинтересован в правильном решении.

person Bogdan    schedule 24.10.2011
comment
Мммм, ладно, кажется сложным, но не за пределами моей досягаемости. Однако возникает вопрос: будут ли файлы pyc выполняться со встроенным исполняемым файлом Python? Я имею в виду, будет ли это работать на любом компьютере с установленным Python или без него? - person Joël; 24.10.2011
comment
Да, они должны быть, если это та же ОС. Я тестировал его только на debian squeeze, но не могу гарантировать. - person Bogdan; 24.10.2011
comment
Я добавил еще несколько деталей о настройке журналирования. Не могли бы вы взглянуть? Возможно, то, как я сконфигурировал свои файлы ресурсов, приводит к проблемам с PyInstaller. - person Joël; 25.10.2011
comment
Второй комментарий о вашем коде: вы используете excluded_sources следующим образом: pyz = PYZ(a.pure - excluded_sources)? Если да, то, возможно, not слишком много в for x in a.pure if *not* x[0].startswith(.... Возможно, я этого не понял, так как он все еще не работает; но наличие pyc файлов все же лучше, чем ничего, если они упакованы для любой версии Python. - person Joël; 25.10.2011
comment
Вот несколько новостей. Проблема заключалась в том, что __file__ не возвращал ожидаемого значения. Итак, я использую sys.argv[0] для определения местоположения вызываемого исполняемого файла. Я надеюсь, что в этом нет побочных эффектов, поскольку это все, что я мог представить, чтобы обойти эту проблему. В любом случае спасибо за вашу помощь! - person Joël; 25.10.2011
comment
@Bogdan: Ваш хакер у меня сработал в Windows. Но у меня есть вопрос. После того, как я запустил pyinstaller после внесения некоторых изменений в мои сценарии python, мне не нужно будет снова запускать pyinstaller для файла .py для создания новой спецификации? Если это так, то мне нужно будет вносить эти изменения каждый раз, когда я буду вносить изменения в скрипт, прежде чем я создам exe. Есть ли способ обойти это? - person Crypto; 07.02.2014