2016-06-05 10 views
4

Ich stehe vor einem sehr seltsamen Problem. Ich habe drei Dateien, die erste enthält die Basisklasse, von der die Klassen in den beiden anderen Dateien erben.Python-Modul-Import funktioniert für eine Datei, schlägt für andere

Das Seltsame ist, gestern hat alles gut funktioniert, aber eine der Dateien funktioniert heute nicht mehr. Ich habe die Importe in der Zwischenzeit nicht berührt.

. 
└── orangecontrib 
    ├──__init__.py 
    └── prototypes 
     ├──__init__.py 
     └── widgets 
      ├──__init__.py 
      ├── owpythagorastree.py 
      ├── owclassificationpythagorastree.py 
      └── owregressionpythagorastree.py 

So sind die Klassifikations- und Regressionsklassen müssen von der Basisklasse erben, und die Importe werden in genau der gleichen Weise:

owclassificationpythagorastree.py

... 
from orangecontrib.prototypes.widgets.owpythagorastree import OWPythagorasTree 
... 

owregressionpythagorastree .py

... 
from orangecontrib.prototypes.widgets.owpythagorastree import OWPythagorasTree 
... 

Doch wenn ich versuche, die beiden Skripte von der Kommandozeile (mit python owregressionpythagorastree.py) die Regressions Widget funktioniert gut, aber die Einstufung Widget erzeugt den folgenden Fehler auszuführen:

Traceback (most recent call last): File "owclassificationpythagorastree.py", line 6, in from orangecontrib.prototypes.widgets.owpythagorastree import OWPythagorasTree ImportError: No module named 'orangecontrib.prototypes'

Dieses mehrmals in anderen passiert ist Projekte auch, aber es sortiert sich schließlich aus. Aber es stört mich, dass ich nicht weiß, was das verursacht.

Ich habe versucht, dies sowohl von meinem regulären Computer und einem Python virtualenv, wo ich das Modul installiert habe (Ich tat dies mit pip install -e . im Basisverzeichnis).

Ich sehe keinen ersichtlichen Grund für dieses Verhalten und es stört mich sehr, so jede Hilfe oder Einsicht, warum dies geschieht und wie es zu beheben wäre, würde geschätzt.


EDIT

Wie gewünscht, lief ich import sys; print(sys.path) an der Spitze der beiden Skripte und es durch diff nach dem Laufen, sie sind beide völlig identisch. Trotzdem poste ich die Ergebnisse hier.

['/home/pavlin/dev/orange3-prototypes/orangecontrib/prototypes/widgets', '/home/pavlin/dev/orange3', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages/setuptools_git-1.1-py3.5.egg', '/home/pavlin/dev/orange-bio', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages/pyqtgraph-0.9.10-py3.5.egg', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages/requests-2.9.1-py3.5.egg', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages/slumber-0.7.1-py3.5.egg', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages/Genesis_PyAPI-1.2.0-py3.5.egg', '/usr/lib/python3.5/site-packages/qt_graph_helpers-0.1.3-py3.5-linux-x86_64.egg', '/home/pavlin/dev/orange3-prototypes', '/usr/lib/python3.5/site-packages', '/home/pavlin/dev/orange3env/lib/python35.zip', '/home/pavlin/dev/orange3env/lib/python3.5', '/home/pavlin/dev/orange3env/lib/python3.5/plat-linux', '/home/pavlin/dev/orange3env/lib/python3.5/lib-dynload', '/usr/lib64/python3.5', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-linux', '/home/pavlin/dev/orange3env/lib/python3.5/site-packages', '/usr/lib/python3.5/site-packages/setuptools-18.7.1-py3.5.egg', '/home/pavlin/.local/lib/python3.5/site-packages']

+0

In jedem Verzeichnis befinden sich '__init __. Py'-Dateien. Ich werde sie der Frage hinzufügen, um Verwirrung zu vermeiden. Dies kann nicht das Problem sein, da die Module eindeutig für eine der Dateien funktionieren, aber nicht für die andere. – Pavlin

+0

Ich kann Ihnen das sagen, zum Beispiel, wenn ich versuche, ein Modul von mir auf dem Desktop zu importieren, wenn ich versuche, es auf der Shell zu importieren, kann ich nicht. Weil Shell auf einem anderen Pfad arbeitet, aber wenn ich es in eine .py-Datei auf dem Desktop importiere, funktioniert es. Shell ist auch auf dem Desktop. Versuche also, sie zu überprüfen, ob sie tatsächlich auf diesem Pfad laufen. Auf einem Pfad zu bleiben bedeutet nicht, dass sie auf diesem Pfad laufen, das ist der Trick. – GLHF

+0

Was ist mit 'von .owpythagorastree importieren OWPythagorasTree'? Oder auch ohne den Punkt? –

Antwort

2

Es sieht aus wie Ihr Problem ist ein nicht vollständiges Verständnis von wie Python Module findet.

Für ein absolute import (dh ein, wo Sie den Namen des ersten Moduls wie import mymodule angeben, und keine Zeit verwenden, um einen relativen Import aus dem Paket zu tun, zu dem der Code, wie from . import mymodule gehört), das Reihenfolge der Lookups ist:

  1. Das aktuelle Verzeichnis.
  2. Alle Verzeichnisse in PYTHONPATH in Ihrer Umgebung.
  3. Alle installierten Systempfade, die auf verschiedene Arten eingestellt werden können.

Um Ihre vollständigen Satz von Pfaden zu sehen, um zu importieren, verwenden Sie:

import sys 
print(sys.path) 

Denken Sie auch daran, dass ein Verzeichnis nur einführbar ist, wenn es eine __init__.py Datei hat -, ob nicht gesagt, dass war der Fall oder nicht mit Ihrem Code.

Daher, sofern Sie das folgende Layout haben:

. 
└── orangecontrib 
    ├── __init__.py 
    └── prototypes 
     ├── __init__.py 
     └── widgets 
      ├── __init__.py 
      ├── owpythagorastree.py 
      ├── owclassificationpythagorastree.py 
      └── owregressionpythagorastree.py 

Ich würde erwarten, dass, wenn Sie python orangecontrib/prototypes/widgets/owclassificationpythagorastree.py aus dem Basisverzeichnis . ausführen, sollten beide gut funktionieren, ohne dass Ihre PYTHONPATH, da Python zu ändern, immer sucht im aktuellen Verzeichnis zuerst nach absolut importierten Modulen.

Wenn Sie aus dem Verzeichnis widgets laufen, würde ich erwarten, dass es nicht funktioniert, es sei denn, Sie hatten zuerst das Basisverzeichnis zu Ihrem PYTHONPATH hinzugefügt.

Als ein allgemeiner Hinweis, außer für sehr kleine Dinge, sollten Sie vermeiden, Modul-Code mit Skript-Code zu mischen, genau aus diesen Gründen! Erstellen Sie separate Python-Skripts, die für die Ausführung über eine Befehlszeile vorgesehen sind, und trennen Sie den Python-Modulcode, der für den Import vorgesehen ist. Vermeiden Sie es, Module zu erstellen, die auch über die Befehlszeile als Skripts ausgeführt werden können.

+0

Beachten Sie auch, dass Sie ernsthaft Situationen vermeiden sollten, in denen Sie Script 'a.py' ausführen, das' b.py' importiert, das wiederum 'a.py' importiert - das kann zu wirklich seltsamen Dingen führen, siehe vorheriges Antwort von mir [hier] (http://stackoverflow.com/a/35725043/5920499), aber ich denke nicht, dass das dein Problem in diesem Fall ist, aber das ist ein weiterer Grund, warum du Modulcode und Skriptcode nicht mischen solltest . – daphtdazz

+0

Vielen Dank für diese Erklärung - ich wusste nicht wirklich, wie Python Dinge importiert hat, also hat es einiges geklärt. Aber leider hilft mir das nicht ... Ich verstehe, dass ich, seit ich das Modul auf dem virtualenv installiert habe, einen absoluten Import machen konnte, der für eine Datei funktioniert, aber nicht für die andere. Ich habe auch versucht, die Skripte aus allen denkbaren Verzeichnissen auszuführen, und das Ergebnis ist auch dasselbe. Der einzige Grund, warum ich die Skripts über die Befehlszeile ausführe, ist das leichtere Debugging. Interessanterweise tritt dieses Problem nur bei Ausführung über die Befehlszeile auf. – Pavlin

+0

Es scheint mir das Problem hier wäre eine obskure Art und Weise wie Python Dateien interpretiert oder etwas Seltsames (ich weiß es wirklich nicht, daher meine Frage), da die Importe in beiden Dateien aus der gleichen Umgebung auf die gleiche Weise gemacht werden, aber das eine läuft gut, und das andere führt zu einem Fehler ... – Pavlin

1

Nur ein Gedanke. Hast du die Berechtigungen überprüft? Vielleicht wurden die Berechtigungen irgendwie durcheinander gebracht und sie geben dir die Probleme.

+0

Die Berechtigungen sind für alle Dateien im Verzeichnis identisch, daher sollte das nicht das Problem sein. – Pavlin

Verwandte Themen