it-swarm.com.de

Python kann nicht aus einem anderen Ordner importiert werden

Ich kann nicht scheinen, dass Python ein Modul in einen Unterordner importiert. Ich erhalte den Fehler, wenn ich versuche, eine Instanz der Klasse aus dem importierten Modul zu erstellen, der Import selbst jedoch erfolgreich ist. Hier ist meine Verzeichnisstruktur:

Server
    -server.py
    -Models
        --user.py

Hier ist der Inhalt von server.py:

from sys import path
from os import getcwd
path.append(getcwd() + "\\models") #Yes, i'm on windows
print path
import user

u=user.User() #error on this line

Und user.py:

class User(Entity):
    using_options(tablename='users')

    username = Field(String(15))
    password = Field(String(64))
    email    = Field(String(50))
    status   = Field(Integer)
    created  = Field(DateTime)

Der Fehler ist: AttributeError: 'Modul'-Objekt hat kein Attribut' Benutzer '

73
ryeguy

Ich glaube, Sie müssen im Models-Verzeichnis eine Datei mit dem Namen __init__.py erstellen, damit Python sie als Modul behandelt.

Dann können Sie tun:

from Models.user import User

Sie können Code in __init__.py einschließen (zum Beispiel Initialisierungscode, den einige verschiedene Klassen benötigen) oder ihn leer lassen. Aber es muss da sein.

110
Dana

Sie müssen __init__.py im Unterordner Models erstellen. Die Datei ist möglicherweise leer. Es definiert ein Paket.

Dann können Sie tun:

from Models.user import User

Lesen Sie alles dazu im Python-Tutorial, hier .

Es gibt auch einen guten Artikel zur Dateiorganisation von Python-Projekten hier .

20
nosklo

benutzer importieren

u = user.User () #fehler in dieser Zeile

Aufgrund des Fehlens von __init__, das oben erwähnt wurde, würden Sie einen ImportError erwarten, der das Problem klarer machen würde.

Sie erhalten keine, da "Benutzer" auch ein in der Standardbibliothek vorhandenes Modul ist. Ihre Import-Anweisung greift nach dieser und versucht, die Benutzerklasse darin zu finden. das gibt es nicht und erst dann bekommst du den fehler.

Im Allgemeinen ist es eine gute Idee, Ihren Import absolut zu machen:

import Server.Models.user

um diese Art von Mehrdeutigkeit zu vermeiden. In Python 2.7 sieht 'import user' überhaupt nicht relativ zum aktuellen Modul aus.

Wenn Sie wirklich relative Importe wünschen, können Sie sie explizit in Python 2.5 und höher verwenden, indem Sie die etwas hässliche Syntax verwenden:

from .user import User
11
bobince

Der richtige Weg zum Importieren eines Moduls in einem übergeordneten Ordner, wenn Sie keine Standardpaketstruktur haben, ist:

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

(Sie können die letzten beiden Zeilen zusammenführen, dies ist jedoch einfacher zu verstehen).

Diese Lösung ist plattformübergreifend und allgemein genug, um unter anderen Umständen nicht geändert zu werden.

8
glarrain

Sie vermissen __init__.py. Aus dem Python-Tutorial:

Die __init__.py-Dateien sind erforderlich für Lass Python die Verzeichnisse als .__ behandeln. Packungen enthalten; dies wird mit .__ gemacht. Verhindern Sie Verzeichnisse mit einem allgemeinen Name, z. B. Zeichenfolge, aus unbeabsichtigtes Ausblenden gültiger Module die später bei der Modulsuche auftreten Pfad. Im einfachsten Fall ist __init__.py kann nur eine leere Datei sein, sie kann jedoch auch die Initialisierung ausführen Code für das Paket oder setzen Sie die Alle Variable wird später beschrieben.

Fügen Sie eine leere Datei mit dem Namen __init__.py in Ihr Models-Verzeichnis ein.

7
Harper Shelby

wie schreibt man den Befehl os.path.dirname.... aus?

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))
1
user3440815

Meine bevorzugte Methode ist, __init__.py für jedes Verzeichnis zu verwenden, das Module enthält, die von anderen Modulen verwendet werden, und überschreiben Sie sys.path im Einstiegspunkt wie folgt:

def get_path(ss):
  return os.path.join(os.path.dirname(__file__), ss)
sys.path += [
  get_path('Server'), 
  get_path('Models')
]

Dadurch werden die Dateien in den angegebenen Verzeichnissen für den Import sichtbar, und ich kann Benutzer aus Server.py importieren.

0
kchoi

Nachdem ich die Antworten dieser Autoren oben durchgesehen hatte - Zorglub29, Tom, Mark, Aaron McMillin, Lucasamaral, JoeyZhao, Kjeld Flarup, Procyclinsur, martin.zaenker, tooty44 und das Problem, mit dem ich konfrontiert war, beseitigt hatte, habe ich gefunden aus einem anderen Anwendungsfall, aufgrund dessen ich mit diesem Problem konfrontiert war. Daher füge ich meine Beobachtungen unten für jedermanns Referenz hinzu.

In meinem Code hatte ich einen zyklischen Import von Klassen. Zum Beispiel:

src
 |-- utilities.py (has Utilities class that uses Event class)  
 |-- consume_utilities.py (has Event class that uses Utilities class)
 |-- tests
      |-- test_consume_utilities.py (executes test cases that involves Event class)

Beim Versuch, python -m pytest tests/test_utilities.py für die Ausführung von in test_utilities.py geschriebenen UTs auszuführen, ist folgender Fehler aufgetreten.

ImportError while importing test module '/Users/.../src/tests/test_utilities.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_utilities.py:1: in <module>
    from utilities import Utilities
...
...
E   ImportError: cannot import name 'Utilities'

Die Art und Weise, wie ich den Fehler behoben habe, bestand darin, meinen Code neu zu faktorisieren, um die Funktionalität in der zyklischen Importklasse zu verschieben, sodass ich den zyklischen Import von Klassen entfernen konnte.

Beachten Sie, ich habe __init__.py Datei in meinem ' src ' Ordner sowie ' tests ' Ordner und konnte trotzdem den ' ImportError ' einfach loswerden durch Re-Factoring des Codes.

Der folgende Stackoverflow-Link enthält viel mehr Details zu Circular Dependency in Python .

0
shekharlondhe