Я запускаю Python-скомпилированную программу Python с одного сервера на нескольких клиентских машинах (подключенных к сетевому диску на каждой машине, скажем, W :).
На Windows XP и более поздних машинах до сих пор не было проблем с подключением Python к W: \ python23.dll (да, я использую Python 2.3.5 для совместимости с W98 и все такое). Затем он использует W: \ zlib.pyd для распаковки файла W: \ library.zip, содержащего все файлы .pyc, такие как os и подобные, которые затем импортируются, и программа не запускается.
Проблема, с которой я сталкиваюсь, возникает на некоторых машинах с Windows 98 SE (примечание: на некоторых компьютерах с Windows 98 SE другие работают без видимых проблем). Что происходит, программа запускается из W :, я предполагаю, что W: \ python23.dll найден (так как я получаю Python ImportErrors, нам нужно иметь возможность выполнить инструкцию импорта Python), но пара вещей не работает:
1) Если W: \ library.zip содержит единственную копию файлов .pyc, я получаю
ZipImportError: can't decompress data; zlib not available
(ерунда, учитывая, что W: \ zlib.pyd IS доступен и отлично работает с машинами XP и выше в одной сети).
2) Если файлы .pyc фактически объединены ВНУТРИ Python exe с помощью py2exe, ИЛИ помещаются в тот же каталог, что и .exe, ИЛИ помещаются в именованный подкаталог, который затем задается как часть переменной PYTHONPATH (например, W : \ pylib), я получаю ImportError: no module named os
(os - первый импортированный модуль, до sys и всего остального).
Если подумать, sys.path не будет доступен для поиска, если ОС была импортирована раньше, чем это возможно? Я попытаюсь изменить порядок этих импортов, но мой вопрос остается открытым: почему это спорадическая проблема, работающая в одних сетях, но не в других? И как мне заставить Python найти файлы, которые находятся внутри самого исполняемого файла, который я запускаю?
У меня есть немедленный доступ к работающей машине с Windows 98 SE, но я получаю доступ только к нерабочей (моей клиентке) каждое утро перед открытием их магазина.
Заранее спасибо!
РЕДАКТИРОВАТЬ: Хорошо, большой шаг вперед. После отладки с помощью PY2EXE_VERBOSE проблема, возникающая на конкретной машине W98SE, заключается в том, что она не использует правильный синтаксис пути при поиске импорта. Во-первых, кажется, что он не читает переменную окружения PYTHONPATH (может быть специфичная для py2exe, о которой я не знаю, например, PY2EXE_VERBOSE).
Во-вторых, он смотрит только в одном месте, прежде чем сдаться (если файлы связаны внутри EXE-файла, он выглядит там. Если нет, он выглядит в файле library.zip).
EDIT 2 : Фактически, согласно this , существует разница между sys.path в интерпретаторе Python и исполняемыми файлами Py2exe. В частности, sys.path contains only a single entry: the full pathname of the shared code archive.
Бла. Нет откатов? Даже не текущий рабочий каталог? Я бы попробовал добавить W:\
в PATH, но py2exe не соответствует каким-либо стандартам поиска системных библиотек, поэтому он не будет работать.
Теперь для интересного. Путь, из которого он пытается загрузить atexit, os и т. Д., Является:
W:\\library.zip\<module>.<ext>
Обратите внимание на одиночную косую черту после library.zip, но двойную косую черту после буквы диска (кто-то поправит меня, если это задумано и должно работать). Похоже, если это строковый литерал, то, поскольку косая черта не удваивается, она читается как (недопустимая) escape-последовательность и печатается необработанный символ (давая W:\library.zipos.pyd, W:\library.zipos.dll, ...
вместо косой черты); если это НЕ строковый литерал, двойная косая черта не может быть normpath'd автоматически (как и должно быть), и поэтому двойная косая черта сбивает с толку загрузчика модуля. Как я уже сказал, я не могу просто set PYTHONPATH=W:\\library.zip\\
, потому что он игнорирует эту переменную.
Может быть, стоит использовать sys.path.append при запуске моей программы, но жесткое кодирование путей к модулям является абсолютным средством LAST, тем более что проблема возникает в ОДНОЙ конфигурации устаревшей ОС.
Есть идеи? У меня есть один, который должен выразить сожаление по поводу sys.path
... мне нужно os
для этого Другой способ - просто добавить os.getenv('PATH')
или os.getenv('PYTHONPATH')
в sys.path ... снова, для чего требуется модуль os
. Модуль site
также не может инициализироваться, поэтому я не могу использовать файл .pth.
Я также недавно попробовал следующий код в начале программы:
for pth in sys.path:
fErr.write(pth)
fErr.write(' to ')
pth.replace('\\\\','\\') # Fix Windows 98 pathing issues
fErr.write(pth)
fErr.write('\n')
Но он не может загрузить linecache.pyc или что-то еще; на самом деле он не может выполнять эти команды, судя по всему. Есть ли способ использовать встроенную функциональность, которая не требует linecache для динамического изменения sys.path? Или я вынужден жестко задавать правильный sys.path?