2017-12-22 19 views
3

Ich habe ein riesiges Problem, Python 3 Importe zu verstehen versuchen (ich benutze Python 3.5). Dies scheint eine Millionen-Dollar-Frage zu sein und ich weiß, dass sie überall beantwortet wurde. Jedoch gelingt es mir nicht wirklich zu verstehen, wie die Dinge gemacht werden sollen; Antworten im Internet sind sehr unterschiedlich. Es tut mir leid im Voraus, wenn dies eine fast doppelte Antwort ist. Ich würde mich über Hinweise auf gutes Lesematerial sehr freuen.Python3 - wie man absolute Importe richtig macht und Pylint glücklich macht

Also habe ich folgendes Dummy-Projekt:

/my_project/main.py 
/my_project/lib/__init__.py 
/my project/lib/my_lib.py 

Wenn möglich, würde Ich mag an:

  • Lage sein, mein Programm als python3 main.py läuft, my_project als aktuelles Arbeitsverzeichnis ist.
  • Ändern Sie die PYTHONPATH nicht zu jeder Zeit.
  • Machen Sie Pyylint glücklich.
  • Verwenden Sie korrekte Python3-Importe.

main.py enthält:

from .lib.my_lib import foo 

if __name__ == '__main__': 
    foo() 

Und foo entsprechend in lib/my_lib.py

Mit dieser Konfiguration definiert ist, erhalte ich:

SystemError: Parent module '' not loaded, cannot perform relative import

ich um die Fehlermeldung zu erhalten, kann durch Importieren wie:

from lib.my_lib import foo 

Aber dann 1) das ist kein Python3 absoluter Import, oder? 2) Pylint klagt: Unable to import 'lib.my_lib' (import-error)

Das nächste, was ich versuchte, ist eine my_project/__init__.py, und importieren wie folgt hinzuzufügen:

from my_project.lib.my_lib import foo 

In diesem Fall Pylint glücklich ist, aber dann kann ich nicht so laufen wie: python3 main.py: ImportError: No module named 'my_project'

Dann kann ich es nur aus dem übergeordneten Verzeichnis als ein Modul ausführen: python3 -m my_project.main.

Also meine Frage ist: ist es überhaupt möglich, die Importe in einer korrekten Weise zu tun, während es immer noch als python3 main.py ausgeführt werden kann?

Vielen Dank!

+0

'von lib.my_lib Import foo' * ist * ein absoluter Import: das aktuelle Arbeitsverzeichnis wird automatisch in' sys.path', als erstes Verzeichnis gerade. – Evert

+0

Um genauer zu sein (und korrekt): Der erste Eintrag in 'sys.path' ist [" ist das Verzeichnis, das das Skript enthält, das zum Aufruf des Python-Interpreters verwendet wurde "] (https://docs.python.org/3 /library/sys.html#sys.path). – Evert

+0

Ich kann das Problem mit Pylint nicht reproduzieren: Ich bekomme keinen Importfehler. – Evert

Antwort

0

ich tun würde, so etwas wie:

/path/README 
/path/requirements.txt 
/path/cleverappname/__main__.py 
/path/cleverappname/__init__.py 
/path/cleverappname/foo.py 
/path/cleverappname/bar.py 

Sie so etwas wie class CleverName(object) in __init__.py und Dinge wie class Foo(object) in foo.py haben Angenommen (gleich für Bar, haben Sie die Idee).

In __main__:

from cleverappname import CleverName 
from cleverappname.foo import Foo 
from cleverappname.bar import Bar 

Aber es braucht man es als Python zu verwenden und nicht ein Skript (was richtig ist, denn das ist, was es ist): python3 -m clevername

Pylint scheint glücklich über Das.

+0

Ich würde relative Importe für Intrapaket-Importe verwenden. Nur für den Fall, dass man sich entscheidet, das Paket umzubenennen (oder wer es installiert, entscheidet sich, es umzubenennen). – Evert

Verwandte Themen