Доступ к программе py2exe по сети в Windows 98 вызывает ImportErrors

Я запускаю программу 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?


person Community    schedule 05.01.2010    source источник
comment
Вы уверены, что у вас есть строка с этими точными символами? Если это printed, значит, они настоящие, и часть с двойной обратной косой чертой может сделать его недопустимым путем. Но обратные косые черты не являются escape-последовательностями, если они находятся в строке Python ... они действуют как escape-последовательности только в строковых литералах (т.е. в исходном коде Python, который компилируется). Дважды проверьте, что у вас есть, или, возможно, распечатайте результат с помощью repr () вокруг него, чтобы мы могли точно увидеть, что там (включите окружающие кавычки в том случае, когда вы вставляете сюда).   -  person Peter Hansen    schedule 08.01.2010
comment
Я не смогу получить доступ к компьютеру клиента до утра понедельника, до открытия его магазина, но я обязательно сделаю это и опубликую здесь результаты :)   -  person    schedule 08.01.2010
comment
Сегодня утром не смог сесть в машину, потому что был занят. Я добавлю код в начале, чтобы заменить \\ на \ в sys.path, и разверну его завтра: посмотрим, сработает ли это.   -  person    schedule 11.01.2010
comment
По крайней мере, сейчас давление спало. Я вручную добавил правильный путь, а затем обнаружил, что машина клиента W98 была слишком медленной. Потребовалось около 20 секунд, чтобы выполнить скрипт Python, который анализирует около 6 параметров командной строки и отправляет их программе на C ++. Продолжу идти по пути, основанного на C ++. Тем не менее, все же хочу обсудить, что могло вызвать это на одной машине W98, а не на другой.   -  person    schedule 14.01.2010


Ответы (1)


Это не прямой ответ, но, возможно, поможет. Вы знакомы с параметром -v в Python? Введите python -h, чтобы узнать больше. Обратите внимание, что эквивалент переменной среды PYTHONVERBOSE для скриптов py2exe'd - PY2EXE_VERBOSE, как описано почти нигде, кроме это сообщение его автора. Очевидно, он может принимать значения 1 или 2, в основном как -v и -vv, хотя это немного отличается от как работает PYTHONVERBOSE.

Также обратите внимание на вашу идею sys.path: импортировали ли вы уже sys или нет, это никак не повлияет на то, сможете ли вы импортировать os. То есть путь Python (отображается в sys.path) всегда доступен в том смысле, что он отражает внутреннюю функцию интерпретатора, которая присутствует независимо от того, импортировали вы модуль sys или нет.

Как и ряд других модулей, sys является встроенным, поэтому его всегда следует импортировать, даже если ваше приложение почти полностью повреждено. Если это поможет, вы можете использовать sys.builtin_module_names, чтобы узнать, что они из себя представляют для вашей версии Python. Если интерпретатор вообще запущен, эта информация будет доступна, поэтому следующая может быть самой маленькой полезной программой, которую вы можете создать, чтобы увидеть, что у вас есть:

import sys
print sys.builtin_module_names

Кроме того, я бы не советовал пробовать что-то необычное, например, объединение файлов .pyc внутри .exe. У вас уже достаточно работы против того, чтобы вы застряли в поддержке Win98, и на вашем месте я бы выбрал самый простой подход, который позволил бы мне выполнить работу и перейти к более интересным областям. Если бы вы могли просто установить Python в обычном режиме и запускать его из исходного кода, вам обязательно стоит подумать об этом! :)

Отредактировано, чтобы включить ссылку на информацию PY2EXE_VERBOSE в комментарий от darvids0n.

person Peter Hansen    schedule 05.01.2010
comment
К сожалению, Питер, он жестко запрограммирован (в приложении, которое я не могу изменить) для запуска этого исполняемого файла py2exe из командной строки (с передачей параметров и т. Д.), Поэтому я не могу установить Python на клиентский компьютер. Спасибо за идеи, я проверю PYTHONVERBOSE и sys.builtin_module_names в целевой системе :) - person ; 06.01.2010
comment
@ darvids0n, Возможно, вызывающей программе не требуется фактический exe, и в этом случае вы можете попробовать просто создать файл trampoline .bat, который вызывает Python с именем вашего скрипта и соответствующими аргументами. . Еще одна мысль, FWIW. - person Peter Hansen; 06.01.2010
comment
Питер, просто перепроверил, и на самом деле это .exe, а не только имя программы. Пэчворк - написать исполняемый файл C ++ для выполнения .bat в командной строке (ужасный, ужасный способ сделать это, но он будет работать). Надеюсь, я смогу решить все это в ближайшем будущем, полностью переписав программу Python на C ++, однако, что является моей конечной целью (быстрее, и это также кажется более стабильным). - person ; 07.01.2010
comment
Я быстро погуглил подробный параметр py2exe, и PY2EXE_VERBOSE = 1 распечатал результат операторов импорта, PY2EXE_VERBOSE = 2 распечатал каждую попытку для каждого оператора импорта. Я попробую использовать это на целевом сайте, это должно дать мне хорошее представление о том, где он смотрит, а где нет. Спасибо за помощь: D - person ; 08.01.2010
comment
Хорошая находка! Я никогда не знал, что у py2exe есть такие дополнительные настройки. Добавлю ссылку на свой ответ для потомков. - person Peter Hansen; 08.01.2010