Я запускаю программу python, скомпилированную с помощью py2exe, с одной серверной машины на нескольких клиентских машинах (подключенных к сетевому диску на каждой машине, скажем, 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 ЕСТЬ доступный и отлично работает с компьютерами 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).
РЕДАКТИРОВАТЬ 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, ...
вместо косой черты); если это НЕ строковый литерал, двойная косая черта не может быть автоматически добавлена к нормальному пути (как и должно быть), и поэтому двойная косая черта сбивает загрузчик модуля с толку. Как я уже сказал, я не могу просто set PYTHONPATH=W:\\library.zip\\
, потому что он игнорирует эту переменную.
Возможно, стоит использовать sys.path.append в начале моей программы, но пути к модулям с жестким кодированием являются абсолютным ПОСЛЕДНИМ средством, тем более что проблема возникает в ОДНОЙ конфигурации устаревшей ОС.
Любые идеи? У меня есть один, который предназначен для нормального пути 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 или что-либо еще в этом отношении; судя по всему, он не может выполнять эти команды. Есть ли способ использовать встроенную функциональность, которая не требует кеширования строк для динамического изменения sys.path? Или я вынужден жестко запрограммировать правильный sys.path?
print
ed, значит, они настоящие, и часть с двойной обратной косой чертой может сделать его недопустимым путем. Но обратные косые черты не являются escape-последовательностями, если они находятся в строке Python ... они действуют как escape-последовательности только в строковых литералах (т.е. в исходном коде Python, который компилируется). Дважды проверьте, что у вас есть, или, возможно, распечатайте результат с помощью repr () вокруг него, чтобы мы могли точно увидеть, что там (включите окружающие кавычки в том случае, когда вы вставляете сюда). - person Peter Hansen   schedule 08.01.2010