Ошибка Py_Initialize - невозможно загрузить кодек файловой системы - PullRequest
56 голосов
/ 17 апреля 2011

Я пытаюсь собрать простой тестовый проект c ++, использующий python 3.2.Проект работает хорошо, но Py_Initialize вызывает фатальную ошибку:

Fatal Python error: Py_Initialize: unable to load the file system codec
LookupError: no codec search functions registered: can't find encoding

Минимальный код:

#include <Python.h>

int main (int, char**)
{
  Py_Initialize ();
  Py_Finalize ();
  return 0;
}

Операционная система - 32-битная Vista.

Используемая версия python - это отладочная сборка python 3.2, собранная из исходников, использующих VC ++ 10.

Файл python_d.exe из той же сборки работает без проблем.

Может кто-нибудь объяснить проблему икак это исправить?Мой собственный гугл-фу меня подводит.

РЕДАКТИРОВАТЬ 1

После просмотра исходного кода python я обнаружил, что, как говорится в сообщении об ошибке, функции поиска кодеков нетбыли зарегистрированы.И codec_register, и PyCodec_Register такие, какими они должны быть.Просто нигде в коде ни одна из этих функций не называется.

Я действительно не знаю, что это значит, так как до сих пор не знаю, когда и откуда эти функции должны были быть вызваны.Код, который вызывает ошибку, полностью отсутствует в источнике моей другой сборки Python (3.1.3).

EDIT 2

Ответил на мой собственный вопрос ниже.

Ответы [ 13 ]

40 голосов
/ 17 апреля 2011

Проверьте переменные окружения PYTHONPATH и PYTHONHOME и убедитесь, что они не указывают на Python 2.x.

http://bugs.python.org/issue11288

28 голосов
/ 11 марта 2013

Части этого были упомянуты ранее, но в двух словах это то, что работало для моей среды, где у меня есть несколько установок Python, и моя глобальная установка среды ОС указывает на установку , отличную от установки один, с которым я пытаюсь работать, когда сталкиваюсь с проблемой.

Убедитесь, что ваша (локальная или глобальная) среда полностью настроена так, чтобы указывать на установку, с которой вы собираетесь работать, например, у вас есть две (или более) установки, скажем, python27 и python33 (извините, это пути Windows, но следующее также должно быть допустимо для эквивалентных путей в стиле UNIX, пожалуйста, дайте мне знать обо всем, что мне здесь не хватает ( вероятно путь к DLL может отличаться)):

C:\python27_x86

C:\python33_x64

Теперь, если вы намереваетесь работать с вашей установкой python33, но ваша глобальная среда указывает на python27, убедитесь, что вы обновляете свою среду как таковую (хотя PATH и PYTHONHOME могут быть необязательными ( например, если вы временно работаете в локальной оболочке)):

PATH="C:\python33_x64;%PATH%"

PYTHONPATH="C:\python33_x64\DLLs;C:\python33_x64\Lib;C:\python33_x64\Lib\site-packages"

PYTHONHOME=C:\python33_x64

Обратите внимание, что вам может понадобиться / захотеть добавить любые другие пути к библиотекам к вашему PYTHONPATH, если этого требует ваша среда разработки, но правильная настройка DLLs, Lib и site-packages имеет первостепенное значение. важность.

Надеюсь, это поможет.

8 голосов
/ 08 мая 2018

Основная причина довольно проста: Python не может найти каталог своих модулей, поэтому он, конечно, не может загрузить encodings тоже

Документ Python по встраиванию говорит "Py_Initialize() вычисляет путь поиска модуля на основе его наилучшего предположения "..." В частности, он ищет каталог с именем lib/pythonX.Y "

Тем не менее, если модули установлены в (просто) lib -относительно двоичного файла python - вышеприведенное предположение неверно.

Хотя в документах говорится, что учитываются PYTHONHOME и PYTHONPATH, мы заметили, что это не так;их фактическое присутствие или содержание не имело никакого значения.

Единственное, что оказало влияние, - это вызов Py_SetPath() с, например, [path-to]\lib в качестве аргумента до Py_Initialize().

Конечно, это только вариант для сценария встраивания, когда у человека есть прямой доступ и контроль над кодом;с готовым решением могут потребоваться специальные шаги для решения проблемы.

5 голосов
/ 31 июля 2017

Наткнулся на то же самое, пытаясь установить brew's python3 под Mac OS! Проблема в том, что в Mac OS homebrew ставит «настоящий» питон на целый уровень глубже, чем вы думаете. Вы могли бы подумать, исходя из доморощенного вывода, что

$ echo $PYTHONHOME
/usr/local/Cellar/python3/3.6.2/
$ echo $PYTHONPATH
/usr/local/Cellar/python3/3.6.2/bin

будет правильным, но вызов $ PYTHONPATH / python3 немедленно завершится с ошибкой 6 «не могу найти кодировки». Это потому, что хотя $ PYTHONHOME выглядит как полная установка, с бином, библиотекой и т. Д., Он НЕ является фактическим Python, который находится в «среде» Mac OS. Сделайте это:

PYTHONHOME=/usr/local/Cellar/python3/3.x.y/Frameworks/Python.framework/Versions/3.x
PYTHONPATH=$PYTHONHOME/bin

(при необходимости подставляя номера версий), и все будет работать нормально.

4 голосов
/ 21 сентября 2012

Я только что столкнулся с точно такой же проблемой (та же версия Python, ОС, код и т. Д.).

Вам просто нужно скопировать каталог Python Lib / в рабочий каталог вашей программы (в VC это каталог, где находится .vcproj)

4 голосов
/ 01 апреля 2012

Начиная с python3k, для запуска требуется модуль кодировок, который находится в каталоге PYTHONHOME \ Lib.Фактически, API Py_Initialize () выполняет инициализацию и импортирует модуль кодировок.Убедитесь, что PYTHONHOME \ Lib находится в sys.path и проверьте, есть ли там модуль кодирования.

3 голосов
/ 01 июня 2016

У меня была эта проблема с python 3.5, anaconda 3, windows 7 32 bit.Я решил это, переместив мои файлы pythonX.lib и pythonX.dll в мой рабочий каталог и вызвав

Py_SetPythonHome(L"C:\\Path\\To\\My\\Python\\Installation");

перед инициализацией, чтобы он мог найти нужные ему заголовки, где мой путь был "... \ Anaconda3 \».Мне потребовался дополнительный шаг вызова Py_SetPythonHome, иначе я бы в итоге получил другие странные ошибки при импорте файлов python.

3 голосов
/ 18 апреля 2011

Похоже, что-то идет не так с версией сборки, которая либо не включает соответствующие кодеки, либо неправильно идентифицирует кодек, используемый для системных API.Поскольку исполняемый файл python_d работает, что он возвращает для os.getfsencoding()?(Используйте C API для вызова этого между вашими вызовами Initialize / Finalize)

2 голосов
/ 23 апреля 2019

У меня была такая же проблема, и я нашел этот вопрос. Однако из ответов здесь я не смог решить мою проблему. Я начал отлаживать код cpython и подумал, что я могу обнаружить ошибку. Поэтому я открыл проблему на трекере Python.

Моя ошибка состояла в том, что я не понял, что Py_SetPath очищает все предполагаемые пути. Таким образом, нужно указать все пути при вызове этой функции.

Для завершения я также скопировал самую важную часть беседы ниже.


Мой оригинальный текст вопроса

Я сам скомпилировал исходники CPython 3.7.3 для Windows с Visual Studio 2017 вместе с некоторыми пакетами, например, например, numpy. Когда я запускаю Python Interpreter, я могу импортировать и использовать numpy. Однако, когда я запускаю тот же сценарий через C-API, я получаю ModuleNotFoundError.

Итак, первое, что я сделал, это проверил, находится ли numpy в моем каталоге site-packages и действительно ли там есть папка с именем numpy-1.16.2-py3.7-win-amd64.egg. (Имеет смысл, потому что интерпретатор Python может найти NumPy)

Следующее, что я сделал, было получить некоторую информацию о переменной sys.path, созданной при запуске скрипта через C-API.

#### sys.path content ####
C:\Work\build\product\python37.zip
C:\Work\build\product\DLLs
C:\Work\build\product\lib
C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2017\PROFESSIONAL\COMMON7\IDE\EXTENSIONS\TESTPLATFORM
C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages

Изучая содержимое sys.path, я заметил две вещи.

  1. C:\Work\build\product\python37.zip имеет правильный путь 'C:\Work\build\product\'. Там просто не было почтового файла. Все мои файлы и каталог были распакованы. Поэтому я заархивировал файлы в архив с именем python37.zip, и это решило ошибку импорта.

  2. C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages неправильно, это должно быть C:\Work\build\product\Lib\site-packages, но я не знаю, как создается этот неправильный путь.

Следующее, что я попробовал, было использовать Py_SetPath(L"C:/Work/build/product/Lib/site-packages") перед вызовом Py_Initialize(). Это привело к

Неустранимая ошибка Python «невозможно загрузить кодировку файловой системы» ModuleNotFoundError: нет модуля с именем 'encodings'

Я создал минимальный проект на c ++ с точно этими двумя вызовами и начал отлаживать Cpython.

int main()
{
  Py_SetPath(L"C:/Work/build/product/Lib/site-packages");
  Py_Initialize();
}

Я отслеживал вызов Py_Initialize() до вызова

static int
zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)

внутри zipimport.c

Комментарий над этой функцией гласит следующее:

Создайте новый экземпляр zipimporter. 'archivepath' должен быть похож на путь объект к zip-файлу или к определенному пути внутри zip-файла. За Например, это может быть /tmp/myimport.zip или '/tmp/myimport.zip/mydirectory', если mydirectory является допустимым каталогом внутри архива. 'ZipImportError' возникает, если 'archivepath' не указывает на действительный Zip-архив. Атрибут «архив» Объект zipimporter содержит имя целевого файла zipfile.

Так что для меня кажется, что C-API ожидает, что путь, заданный с помощью Py_SetPath, будет путем к zip-файлу. Это ожидаемое поведение или это ошибка? Если это не ошибка, есть ли способ изменить это так, чтобы он также мог обнаруживать каталоги?

PS: ModuleNotFoundError не возникла у меня при использовании Python 3.5.2+, который я использовал в своем проекте ранее. Я также проверил, установил ли я какие-либо переменные окружения PYTHONHOME или PYTHONPATH, но не увидел ни одной из них в своей системе.


Ответ

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

Короткий ответ: вам нужно убедиться, что Python может найти каталог Lib/encodings, обычно помещая стандартную библиотеку в sys.path. Py_SetPath очищает все выведенные пути, поэтому вам нужно указать все места, которые Python должен искать. (Правила того, как Python выглядит автоматически, сложны и различаются в зависимости от платформы, и я очень хочу это исправить.)

Пути, которые не существуют, в порядке, и это zip-файл.Вы можете поместить stdlib в zip-файл, и он будет найден автоматически, если вы назовете его по умолчанию, но вы также можете оставить его разархивированным и сослаться на каталог.

Полный обзор встраиваниябольше, чем я готов набрать на моем телефоне.Надеюсь, этого достаточно, чтобы вы пошли сейчас.

2 голосов
/ 30 марта 2018

Для меня это произошло, когда я обновил Python 64 bit с 3.6.4 до 3.6.5 .В результате возникла ошибка типа "невозможно извлечь файл python.dll. У вас есть разрешения."

Pycharm также не удалось загрузить интерпретатор, хотя я перезагрузил его в настройках.Выполнение команды python выдало ту же ошибку с режимом администратора и без него.

Причина

Произошла ошибка при установке Python, включает папку в каталоге установки Python C: \ Users \ USERNAME \ AppData \ Local \ Programs \ Python\ Python36 отсутствует

Переустановка Python также не решит проблему. (Не удаление и установка)

Решение

Повторное удаление Python и установка Python.

Поскольку запущенный установщик просто извлекал те же файлы, за исключением папки include

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...