1089 Stimmen

Importieren von Modulen aus dem übergeordneten Ordner

Ich verwende Python 2.5.

Dies ist mein Ordnerbaum:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(Ich habe auch __init__.py in jedem Ordner, hier aus Gründen der Lesbarkeit weggelassen)

Wie importiere ich die nib Modul aus dem Inneren des life Modul? Ich hoffe, dass es möglich ist, ohne an sys.path herumzubasteln.

Hinweis: Das Hauptmodul, das ausgeführt wird, befindet sich in der ptdraft Ordner.

1 Stimmen

Wie ist Ihr PYTHONPATH eingestellt?

2 Stimmen

Ross: Ich habe es mir angesehen. Was soll ich dagegen tun? Ich habe bereits eine __init__.py . S.Lott: Ich weiß nicht, wie ich das überprüfen kann...

4 Stimmen

Echo $PYTHONPATH aus der Shell; import sys; print sys.path aus Python heraus. docs.python.org/tutorial/

6voto

Thomas R Punkte 633

Tengo un Lösung speziell für git-repositories .

Zuerst habe ich sys.path.append('..') und ähnliche Lösungen. Dies führt insbesondere dann zu Problemen, wenn Sie Dateien importieren, die ihrerseits Dateien mit sys.path.append('..') .

Ich habe dann beschlossen, immer das Root-Verzeichnis des Git-Repositorys anzuhängen. In einer Zeile würde es so aussehen:

sys.path.append(git.Repo('.', search_parent_directories=True).working_tree_dir)

Oder ausführlicher, etwa so:

import os
import sys
import git
def get_main_git_root(path):
    main_repo_root_dir = git.Repo(path, search_parent_directories=True).working_tree_dir
    return main_repo_root_dir
main_repo_root_dir = get_main_git_root('.')
sys.path.append(main_repo_root_dir)

Zur ursprünglichen Frage: Basierend auf dem Root-Verzeichnis des Repositorys würde der Import wie folgt aussehen

import ptdraft.nib

oder

import nib

0 Stimmen

Übrigens: So wird die Git-Bibliothek installiert: pip install GitPython

2voto

Sida Zhou Punkte 3051

Unsere Ordnerstruktur:

/myproject
  project_using_ptdraft/
    main.py
  ptdraft/
    __init__.py
    nib.py
    simulations/
      __init__.py
      life/
        __init__.py
        life.py

Ich verstehe das so, dass ich eine paketorientierte Sichtweise habe. Das Paket Root ist ptdraft da es die oberste Ebene ist, die Folgendes enthält __init__.py

Alle Dateien innerhalb des Pakets können absolute Pfade (relativ zum Paketstamm) für Importe verwenden, zum Beispiel in life.py haben wir einfach:

import ptdraft.nib

Um jedoch die life.py für Paketentwicklungs-/Testzwecke, anstelle von python life.py müssen wir verwenden:

cd /myproject
python -m ptdraft.simulations.life.life

Es ist zu beachten, dass wir an dieser Stelle nicht mit einem Pfad herumspielen müssen.


Noch verwirrender wird es, wenn wir die ptdraft Paket, und wir wollen es in einem Treiberskript verwenden, das notwendigerweise außerhalb des ptdraft Paketordner, auch bekannt als project_using_ptdraft/main.py müssten wir mit Pfaden hantieren:

import sys
sys.path.append("/myproject")  # folder that contains ptdraft
import ptdraft
import ptdraft.simulations

und verwenden python main.py um das Skript ohne Probleme auszuführen.

Nützliche Links:

2voto

Miroslav Hinkov Punkte 21

Ich habe den Eindruck, dass Sie das übergeordnete Modul nicht unbedingt importieren müssen. Nehmen wir an, in nib.py gibt es func1() und data1, die man in life.py verwenden muss

nib.py

import simulations.life.life as life
def func1():
   pass
data1 = {}
life.share(func1, data1)

Leben.py

func1 = data1 = None

def share(*args):
   global func1, data1
   func1, data1 = args

Und nun haben Sie Zugriff auf func1 und data in life.py. Natürlich müssen Sie darauf achten, sie in life.py zu füllen, bevor Sie versuchen, sie zu verwenden,

1voto

user3181121 Punkte 99

Zusammenarbeit mit Bibliotheken. Erstellen Sie eine Bibliothek namens nib, installieren Sie sie mit setup.py, lassen Sie sie in site-packages residieren und Ihre Probleme sind gelöst. Du musst nicht alles, was du machst, in ein einziges Paket packen. Brechen Sie es in Stücke auf.

3 Stimmen

Ihre Idee ist gut, aber manche Leute möchten vielleicht ihr Modul mit ihrem Code bündeln - vielleicht um es portabel zu machen und nicht zu verlangen, dass sie ihre Module in site-packages jedes Mal, wenn sie es auf einem anderen Computer ausführen.

1voto

Casper Hansen Punkte 363

Ich hatte ein Problem, bei dem ich eine Flask-Anwendung importieren musste, die einen Import hatte, der auch Dateien in separaten Ordnern importieren musste. Dies ist teilweise mit Remi's Antwort aber nehmen wir an, wir hätten ein Repository, das wie folgt aussieht:

.
 service
     misc
         categories.csv
     test
         app_test.py
    app.py
    pipeline.py

Bevor Sie dann das App-Objekt aus dem app.py Datei ändern wir das Verzeichnis eine Ebene höher, so dass wir beim Importieren der Anwendung (die die pipeline.py ), können wir auch verschiedene Dateien wie eine csv-Datei einlesen.

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)

os.chdir('../')
from app import app

Nachdem Sie die Flask-Anwendung importiert haben, können Sie mit os.chdir('./test') damit Ihr Arbeitsverzeichnis nicht verändert wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X