Py_Initialize schlägt fehl - der Dateisystem-Codec kann nicht geladen werden

70

Ich versuche, ein einfaches C ++ - Testprojekt zusammenzustellen, das einen eingebetteten Python 3.2-Interpreter verwendet. Das Projekt funktioniert einwandfrei, aber Py_Initialize löst einen schwerwiegenden Fehler aus:

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

Minimaler Code:

#include <Python.h>

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

Das Betriebssystem ist 32bit Vista.

Die verwendete Python-Version ist ein Python 3.2-Debug-Build, der aus Quellen mit VC ++ 10 erstellt wurde.

Die Datei python_d.exe aus demselben Build wird problemlos ausgeführt.

Könnte jemand das Problem erklären und wie man es behebt? Mein eigenes Google-Fu versagt mir.

BEARBEITEN 1

Nachdem ich den Python-Quellcode durchgesehen habe, habe ich festgestellt, dass, wie der Fehler sagt, keine Codec-Suchfunktionen registriert wurden. Beide codec_registerundPyCodec_Register sind so, wie sie sein sollten. Es ist nur so, dass nirgendwo im Code eine dieser Funktionen aufgerufen wird.

Ich weiß nicht genau, was das bedeutet, da ich immer noch keine Ahnung habe, wann und von wo diese Funktionen hätten aufgerufen werden sollen. Der Code, der den Fehler auslöst, fehlt vollständig in der Quelle meines anderen Python-Builds (3.1.3).

BEARBEITEN 2

Beantwortete meine eigene Frage unten.

Anton
quelle

Antworten:

50

Überprüfen Sie die PYTHONPATHund PYTHONHOMEUmgebungsvariablen und stellen Sie sicher , sie weisen nicht auf Python 2.x.

http://bugs.python.org/issue11288

Troydm
quelle
1
Wo sind die Systemvariablen PYTHONPATH und PYTHONHOME? Sollen sie sich in Eigenschaften / Erweiterte Systemeinstellungen / Umgebungsvariablen / Systemvariablen befinden? Wenn ja, ich hatte keine von ihnen, dann habe ich mich dazu gebracht, die entsprechenden Pfade meiner Anaconda env zu setzen. Aber dieses Mal lief Conda Terminal nicht.
Bit_scientist
1
@voo_doo Auf Ihrer Shell können Sie mit z echo $PYTHONPATH. Nicht eingestellt mit unset PYTHONPATH.
Spinup
38

Teile davon wurden bereits erwähnt, aber kurz gesagt, dies funktionierte für meine Umgebung, in der ich mehrere Python-Installationen habe und meine globale Betriebssystemumgebung so eingerichtet ist, dass sie auf eine andere Installation verweist als die, mit der ich zu arbeiten versuche, wenn ich auf die stoße Problem.

Stellen Sie sicher, dass Ihre (lokale oder globale) Umgebung vollständig eingerichtet ist, um auf die Installation zu verweisen, mit der Sie arbeiten möchten, z. B. wenn Sie zwei (oder mehr) Installationen haben, z. B. python27 und python33 (sorry, dies sind Windows-Pfade, aber die Folgendes sollte auch für äquivalente Pfade im UNIX-Stil gelten. Bitte teilen Sie mir alles mit, was mir hier fehlt (wahrscheinlich kann der Pfad der DLLs abweichen):

C:\python27_x86

C:\python33_x64

Wenn Sie nun beabsichtigen, mit Ihrer python33-Installation zu arbeiten, Ihre globale Umgebung jedoch auf python27 verweist, stellen Sie sicher, dass Sie Ihre Umgebung als solche aktualisieren (während PATHund PYTHONHOME möglicherweise optional (z. B. wenn Sie vorübergehend in einer lokalen Shell arbeiten)):

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

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

PYTHONHOME=C:\python33_x64

Beachten Sie , dass Sie vielleicht brauchen / wollen alle anderen Bibliothekspfade zu Ihrem anhängen , PYTHONPATHwenn sie von Ihrer Entwicklungsumgebung erforderlich, aber mit Ihren DLLs, Libund site-packagesrichtig Set-up ist von zentraler Bedeutung.

Hoffe das hilft.

Bossi
quelle
1
Ich hatte dieses Problem mit Pythonnet. Das Anhängen Libdes Pfads meines Ordners an PythonEngine.PythonPathhat den Trick ausgeführt. Vielen Dank!
sebrockm
Vielen Dank. Ich hatte dieses Problem mit dem No-Modul namens Codierungen. Das Einstellen des PYTHONPATH wie oben beschrieben hat bei mir funktioniert.
Lionel Yu
Freut mich zu hören, dass es hilfreich war!
Bossi
@bossi Als ich wie erwähnt erwähnte (aber nur mit anaconda env), funktionierte das Conda-Terminal nicht.
Bit_scientist
@voo_doo - ich bin nicht mit Anaconda env vertraut , sondern als Umwelt - Manager, es wickelt möglicherweise diese env vars und möglicherweise benutzerdefinierte Aktualisierung / Konfiguration erfordern PATH, PYTHONPATH, PYTHONHOMEusw.?
Bossi
22

Der Kern Grund ist ganz einfach: Python nicht sein Module Verzeichnis finden, so ist es natürlich nicht geladen werden kann encodingsauch,

In Python-Dokument zum Einbetten heißt es: " Py_Initialize()Berechnet den Modul-Suchpfad anhand seiner besten Vermutung." ... "Insbesondere wird nach einem Verzeichnis mit dem Namen lib/pythonX.Y" "gesucht.

Wenn die Module jedoch (nur) lib- relativ zur Python-Binärdatei - installiert sind , ist die obige Vermutung falsch.

Obwohl die Dokumente dies sagen PYTHONHOMEund berücksichtigt PYTHONPATHwerden, haben wir festgestellt, dass dies nicht der Fall war. ihre tatsächliche Anwesenheit oder ihr tatsächlicher Inhalt war völlig irrelevant.

Das einzige, was sich auswirkte, war ein Aufruf Py_SetPath()mit zB [path-to]\libals Argument zuvor Py_Initialize() .

Sicher ist dies nur eine Option für ein Einbettungsszenario, in dem man direkten Zugriff und Kontrolle über den Code hat. Bei einer vorgefertigten Lösung können spezielle Schritte erforderlich sein, um das Problem zu lösen.

Semanino
quelle
2
Beste und genaueste Antwort, IMO. Gewählt!
Leslie N
^ was Leslie gesagt hat.
mlvljr
7

Bin beim Versuch, Brews Python3 unter Mac OS zu installieren, auf dasselbe gestoßen! Das Problem hierbei ist, dass Homebrew unter Mac OS die "echte" Python eine ganze Ebene tiefer legt, als Sie denken. Sie würden von der Homebrew-Ausgabe denken, dass

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

wäre richtig, aber das Aufrufen von $ PYTHONPATH / python3 stürzt sofort mit dem Abbruch 6 "Codierungen können nicht gefunden werden" ab. Dies liegt daran, dass $ PYTHONHOME zwar wie eine vollständige Installation mit einem Bin, einer Bibliothek usw. aussieht, es jedoch NICHT das eigentliche Python ist, das sich in einem Mac OS "Framework" befindet. Mach das:

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

(ggf. Versionsnummern ersetzen) und es wird gut funktionieren.

user405
quelle
Dankeschön! Das zweite Beispiel funktioniert einwandfrei auf meinem MacOS :-)
CeDeROM
Mit pyenv und zsh half es auch, die Variablen zu deaktivieren, anstatt sie leer zu setzen.
Peterhil
5

Ab python3k benötigt der Start das Codierungsmodul, das sich im Verzeichnis PYTHONHOME \ Lib befindet. Tatsächlich führt die API Py_Initialize () die Initialisierung durch und importiert das Codierungsmodul. Stellen Sie sicher, dass sich PYTHONHOME \ Lib in sys.path befindet, und überprüfen Sie, ob das Codierungsmodul vorhanden ist.

Tempbottle
quelle
5

Ich hatte dieses Problem mit Python 3.5, Anaconda 3, Windows 7 32 Bit. Ich habe es gelöst, indem ich meine Dateien pythonX.lib und pythonX.dll in mein Arbeitsverzeichnis verschoben und aufgerufen habe

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

vor der Initialisierung, damit es die benötigten Header finden kann, wo mein Pfad zu "... \ Anaconda3 \" war. Der zusätzliche Schritt zum Aufrufen von Py_SetPythonHome war für mich erforderlich, da sonst andere seltsame Fehler beim Importieren von Python-Dateien auftreten würden.

aquirdturtle
quelle
liefern auch an pybind11
heLomaN
4

Ich bin gerade auf genau das gleiche Problem gestoßen (dieselbe Python-Version, dasselbe Betriebssystem, denselben Code usw.).

Sie müssen nur das Lib / -Verzeichnis von Python in das Arbeitsverzeichnis Ihres Programms kopieren (auf VC ist es das Verzeichnis, in dem sich die .vcproj befindet).

Calvin1602
quelle
5
Das mag funktionieren, aber ich würde sagen, das ist keine sehr gute Lösung. Es löst nicht das Problem, warum der Suchpfad falsch ist, sondern vermeidet ihn nur und bringt auch den Verzeichnisbaum durcheinander. Ich schlage vor, einen Haltepunkt in die find_moduleFunktion in Python/import.cund / oder die calculate_pathFunktion in PC/getpathp.c(IIRC) einzufügen, um herauszufinden, wo sie tatsächlich aussieht und warum sie nicht Ihren Erwartungen entspricht. Trotzdem bin ich vielleicht ein Perfektionist, wenn es um diese Dinge geht.
Anton
1
Ich stimme nicht zu. Es ist eine absolut gültige Lösung: Sie binden Ihr eigenes Python ein, Sie wissen, wo es ist und was es enthält. Es ist auch einfacher weiterzuverteilen (denken Sie daran, dass Sie in den alten Tagen von Blender die richtige Version von Python installieren mussten oder es zur Laufzeit abstürzen würde? Jetzt ist es in ProgramFiles / Blender / gebündelt.) Ich denke, es hängt von Ihrer Verwendung ab.
Calvin1602
Oh warte ... Du hast gemeint (und geschrieben, ich sehe jetzt), das Verzeichnis zu kopieren, nicht wahr? Ich habe das als Kopieren des Inhalts des Verzeichnisses gelesen, was chaotisch wäre ... Tut mir leid.
Anton
Ich hatte dieses Problem mit Python 3.5, Anaconda 4.0 Distribution. Dies hat es behoben, danke
aquirdturtle
3

Es scheint, dass beim Release-Build ein Fehler auftritt, der entweder nicht die entsprechenden Codecs enthält oder den für System-APIs zu verwendenden Codec falsch identifiziert. python_dWofür kehrt das zurück, da die ausführbare Datei funktioniert os.getfsencoding()? (Verwenden Sie die C-API, um dies zwischen Ihren Initialisierungs- / Finalisierungsaufrufen aufzurufen.)

ncoghlan
quelle
Das Debuggen sagt mir, dass sys.getfilesystemencoding'mbcs' korrekt zurückgegeben wird.
Anton
Was passiert, wenn Sie einen Release-Build von 3.2 erstellen und diesen mit Ihrer ausführbaren Release-Modus-Datei verknüpfen?
Ncoghlan
3

Ich hatte das gleiche Problem und fand diese Frage. Aufgrund der Antworten hier konnte ich mein Problem jedoch nicht lösen. Ich fing an, den Cpython-Code zu debuggen und dachte, ich könnte einen Fehler entdecken. Daher habe ich ein Problem im Python Issue Tracker geöffnet.

Mein Fehler war, dass ich nicht verstanden habe, dass Py_SetPathalle abgeleiteten Wege frei sind. Man muss also alle Pfade setzen, wenn man diese Funktion aufruft.

Zum Abschluss habe ich auch den wichtigsten Teil des Gesprächs unten kopiert.


Mein ursprünglicher Problemtext

Ich habe die Quelle von CPython 3.7.3 selbst unter Windows mit Visual Studio 2017 zusammen mit einigen Paketen wie z. B. numpy kompiliert. Wenn ich den Python Interpreter starte, kann ich numpy importieren und verwenden. Wenn ich jedoch dasselbe Skript über die C-API ausführe, erhalte ich eine ModuleNotFoundError.

Als erstes habe ich überprüft, ob sich numpy in meinem Site-Packages-Verzeichnis befindet und tatsächlich ein Ordner mit dem Namen numpy-1.16.2-py3.7-win-amd64.egg vorhanden ist. (Sinnvoll, da der Python-Interpreter numpy finden kann)

Als nächstes habe ich einige Informationen über die Variable sys.path erhalten, die beim Ausführen des Skripts über die C-API erstellt wurde.

#### 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

Als ich den Inhalt von sys.path untersuchte, bemerkte ich zwei Dinge.

  1. C:\Work\build\product\python37.ziphat den richtigen Weg ' C:\Work\build\product\'. Es gab einfach keine Zip-Datei. Alle meine Dateien und Verzeichnisse wurden entpackt. Also habe ich die Dateien in ein Archiv namens python37.zip gezippt und dadurch den Importfehler behoben.

  2. C:\Users\rvq\AppData\Roaming\Python\Python37\site-packagesist falsch, sollte es sein, C:\Work\build\product\Lib\site-packagesaber ich weiß nicht, wie dieser falsche Pfad erstellt wird.

Das nächste, was ich versuchte, war Py_SetPath(L"C:/Work/build/product/Lib/site-packages")vor dem Anruf zu verwenden Py_Initialize(). Dies führte zu

Schwerwiegender Python-Fehler 'Dateisystemcodierung kann nicht geladen werden' ModuleNotFoundError: Kein Modul mit dem Namen 'encodings'

Ich habe ein minimales C ++ - Projekt mit genau diesen beiden Aufrufen erstellt und mit dem Debuggen von Cpython begonnen.

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

Ich verfolgte den Anruf von Py_Initialize()bis zum Anruf von

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

innerhalb von zipimport.c

Der Kommentar über dieser Funktion besagt Folgendes:

Erstellen Sie eine neue Zipimporter-Instanz. 'archivepath' muss ein pfadähnliches Objekt zu einer Zip-Datei oder zu einem bestimmten Pfad innerhalb einer Zip-Datei sein. Beispielsweise kann es sich um '/tmp/myimport.zip' oder '/tmp/myimport.zip/mydirectory' handeln, wenn mydirectory ein gültiges Verzeichnis im Archiv ist. 'ZipImportError' wird ausgelöst, wenn 'archivepath' nicht auf ein gültiges Zip-Archiv verweist. Das Attribut 'archive' des zipimporter-Objekts enthält den Namen der Ziel-Zip-Datei.

Für mich scheint die C-API zu erwarten, dass der mit Py_SetPath festgelegte Pfad ein Pfad zu einer Zip-Datei ist. Ist das erwartetes Verhalten oder ist es ein Fehler? Wenn es sich nicht um einen Fehler handelt, gibt es eine Möglichkeit, dies zu ändern, damit auch Verzeichnisse erkannt werden können?

PS: Der ModuleNotFoundError ist bei Verwendung von Python 3.5.2+, der Version, die ich zuvor in meinem Projekt verwendet habe, bei mir nicht aufgetreten. Ich habe auch überprüft, ob ich Umgebungsvariablen für PYTHONHOME oder PYTHONPATH festgelegt habe, aber keine davon auf meinem System gesehen.


Antworten

Dies ist wahrscheinlich mehr als alles andere ein Dokumentationsfehler. Wir sind gerade dabei, die Initialisierung neu zu gestalten, daher ist es ein guter Zeitpunkt, dieses Feedback beizutragen.

Die kurze Antwort lautet, dass Sie sicherstellen müssen, dass Python das Lib/encodingsVerzeichnis finden kann , indem Sie normalerweise die Standardbibliothek einfügen sys.path. Py_SetPathlöscht alle abgeleiteten Pfade, daher müssen Sie alle Stellen angeben, an denen Python suchen soll. (Die Regeln, nach denen Python automatisch aussieht, sind kompliziert und variieren je nach Plattform. Dies möchte ich unbedingt korrigieren.)

Pfade, die nicht existieren, sind in Ordnung, und das ist die Zip-Datei. Sie können die stdlib in eine Zip-Datei einfügen. Sie wird automatisch gefunden, wenn Sie sie als Standardpfad angeben. Sie können sie jedoch auch entpackt lassen und auf das Verzeichnis verweisen.

Ein vollständiger Überblick über das Einbetten ist mehr als ich bereit bin, auf meinem Telefon zu tippen. Hoffentlich ist das genug, um dich jetzt zum Laufen zu bringen.

ROSA
quelle
2

Ich hatte das Problem und bastelte an verschiedenen hier genannten Lösungen. Da ich mein Projekt anscheinend in Visual Studio ausgeführt habe, musste ich den Umgebungspfad in Visual Studio und nicht den Systempfad festlegen.

Das Hinzufügen eines einfachen PYTHONHOME = PATH \ TO \ PYTHON \ DIR in der Umgebung der Projektlösung \ properties \ löste das Problem.

user1538653
quelle
2

Für mich geschah dies, als ich Python 64 Bit von 3.6.4 auf 3.6.5 aktualisierte . Es gab einen Fehler wie "python.dll kann nicht extrahiert werden. Haben Sie Berechtigungen?".

Pycharm konnte auch den Interpreter nicht laden, obwohl ich ihn in den Einstellungen neu geladen habe. Das Ausführen des pythonBefehls gab denselben Fehler mit und ohne Administratormodus aus.

Grund

Bei der Installation von Python ist ein Fehler aufgetreten. Der Ordner include im Python-Installationsverzeichnis C: \ Users \ USERNAME \ AppData \ Local \ Programs \ Python \ Python36 fehlte

Durch die Neuinstallation von Python wird das Problem ebenfalls nicht behoben. (Nicht entfernen und installieren)

Lösung

Deinstallieren Sie Python und installieren Sie Python erneut.

Weil das laufende Installationsprogramm nur dieselben Dateien mit Ausnahme des Include-Ordners extrahierte

Morse
quelle
2

In meinen Fällen, wenn Sie für Windows mehrere Python-Versionen installiert haben PYTHONPATHund auf eine Version verweisen, haben die anderen nicht funktioniert. Ich fand, dass, wenn Sie nur entfernen PYTHONPATH, sie alle gut funktionieren

AmitE
quelle
0

Aus irgendeinem Grund kann die Python-DLL das Codierungsmodul nicht finden. Die ausführbare Datei python.exe findet sie anscheinend, weil sie den erwarteten relativen Pfad hat. Das Ändern des Suchpfads funktioniert.

Der Grund für all das? Weiß nicht, aber zumindest funktioniert es. Ich vermute sehr, dass ich irgendwo einen Tippfehler habe, das ist normalerweise der Grund für seltsame Fehler, wie es scheint.

Anton
quelle
3
Über welchen Suchpfad sprechen Sie hier?
Piotr Dobrogost
Der Pfad, in dem Python nach Modulen sucht. Das war vor einer Weile, also erinnere ich mich nicht genau, wo oder wie.
Anton
3
Können Sie zeigen, was Sie getan haben, um es in Ihrer Lösung zu ändern?
Hack-R
@ Hack-R Leider nein. Ich habe mich umgesehen, aber ich kann das Projekt nicht mehr finden und es ist sehr wahrscheinlich, dass es seit einigen Jahren nicht mehr existiert. Ich bedaure eher, dass ich keine detailliertere Antwort gegeben habe, als ich die Gelegenheit dazu hatte.
Anton
29
Warum ist dies eine akzeptierte Antwort? In dieser Antwort gibt es keine Lösung.
Ska
0

Für diejenigen , die in Visual Studiofügen Sie einfach die include, Libund libsVerzeichnisse auf die Include Directoriesund Library Directoriesunter Projects Properties -> Configuration Properties > VC++ Directories:

Zum Beispiel habe ich Anaconda3auf meinem System und arbeite mit Visual Studio 2015So sehen die Einstellungen aus (beachten Sie die Verzeichnisse Include und Library): Geben Sie hier die Bildbeschreibung ein

Bearbeiten:

Wie auch durch die Bossi- Einstellung PYTHONPATHin Ihrem Benutzerbereich hervorgehoben, Environment Variablesscheint notwendig. Eine Beispieleingabe kann wie folgt aussehen (in meinem Fall):

C:\Users\Master\Anaconda3\Lib;C:\Users\Master\Anaconda3\libs;C:\Users\Master\Anaconda3\Lib\site-packages;C:\Users\Master\Anaconda3\DLLs

ist notwendig, wie es scheint.

Außerdem müssen Sie neu starten, Visual Studionachdem Sie die PYTHONPATHUmgebungsvariablen in Ihrem Benutzer eingerichtet haben, damit die Änderungen wirksam werden.

Beachten Sie auch Folgendes:

Stellen Sie sicher, dass die PYTHONHOMEUmgebungsvariable auf den Python-Interpreter eingestellt ist, den Sie verwenden möchten. Die C ++ - Projekte in Visual Studio stützen sich auf diese Variable, um Dateien zu finden, z. B. python.hdie beim Erstellen einer Python-Erweiterung verwendet werden.

Rika
quelle