Importul de module de la folderul părinte

Sunt de funcționare Python 2.5.

Acesta este dosarul meu de copac:

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

(Am, de asemenea, `init.py în fiecare dosar, a omis aici pentru lizibilitate)

Cum pot importa one modulul din interiorul "viață" module? Sper că este posibil să se facă fără tinkering cu sys.calea.

Notă: modulul principal este condusă în anii ptdraft folder.

Comentarii la întrebare (11)

Ai putea folosi relativă a importurilor (python >= 2.5):

from ... import nib

(Ceea ce este Nou în Python 2.5) PEP 328: Absolută și Relativă a Importurilor

EDITA: adăugat un alt punct '.' pentru a merge în sus două pachete

Comentarii (10)

Relativă a importurilor (ca în la .. import mymodule) funcționează numai într-un pachet. Pentru a importa 'mymodule' care este în directorul părinte al tău curent module:

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) 

import mymodule

edit: a __file__ atribut nu este întotdeauna dat. În loc de a folosi os.calea.abspath(__file__) am sugerat acum folosind inspecta modul de a prelua nume de fișier (și calea) fișierului curent

Comentarii (5)
Soluția

Se pare că problema nu este legată de modul de a fi în directorul părinte sau ceva de genul asta.

Aveți nevoie pentru a adăuga un director care conține `ptdraft să PYTHONPATH

Ai spus că import nib a lucrat cu tine, înseamnă că probabil ați adăugat ptdraft în sine (nu părintele său) să PYTHONPATH.

Comentarii (2)

Am postat un răspuns similar, de asemenea, la întrebarea privind importurile de frate pachete. Puteți vedea aici. Următoarele este testat cu Python 3.6.5, (Anaconda, conda 4.5.1), Windows 10 mașină.

Soluție fără sys.calea hacks

Setup

Presupun că același folder structura în cauză

.
└── ptdraft
    ├── __init__.py
    ├── nib.py
    └── simulations
        ├── __init__.py
        └── life
            ├── __init__.py
            └── life.py

Eu numesc . folderul rădăcină, și în cazul meu, este situat în C:\tmp\test_imports`.

Pașii

  1. Adauga un setup.py în folderul rădăcină

    Conținutul setup.py poate fi pur și simplu

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

Practic "orice" setup.py ar lucra. Acesta este doar un minim exemplu de lucru.

  1. Folosiți un mediu virtual

    Dacă sunteți familiarizat cu mediile virtuale, activa unul, și treceți la pasul următor. Utilizarea de medii virtuale nu sunt absolut necesare, dar ei vor într-adevăr ** te ajute pe termen lung (atunci când aveți mai mult de 1 proiect în curs de desfășurare..). Pașii de bază sunt (rula în folderul rădăcină)

  • Creați virtual env
  • python -m venv venv
  • Activa virtual env
  • . /venv/bin/activa (Linux) sau,. /venv/Script-uri/activa (Win)

Pentru a afla mai multe despre acest lucru, doar Google "python virtual env tutorial" sau similare. Probabil nu ai nevoie de alte comenzi decât crearea, activarea și dezactivarea.

Odată ce ați făcut și activat un mediu virtual, consola ar trebui să dea numele de mediul virtual în paranteză

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
  1. pip instala proiect în stare editabil

    Instalați dumneavoastră de top la nivel de pachet myproject "folosind" pip`. Trucul este de a utiliza "- e " pavilion atunci când faci instala. În acest fel este instalat într-o stare editabil, și toate modificările aduse .py fișierele vor fi automat incluse în pachet instalat.

În directorul rădăcină, rula

pip instala -e . (notă punct, ea vine de la "directorul curent")

Puteți vedea, de asemenea, că este instalat cu ajutorul pip freeze

(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
  Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0
  1. Import prin adăugarea `mainfolder la fiecare import

În acest exemplu, mainfolder "ar fi" ptdraft. Acest lucru are avantajul că nu va rula în numele coliziunile cu alte nume de module (de la python biblioteca standard sau module 3rd party).


Exemplu De Utilizare

nib.py

def function_from_nib():
    print('I am the return value from function_from_nib!')

life.py

from ptdraft.nib import function_from_nib

if __name__ == '__main__':
    function_from_nib()

De funcționare life.py

(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!
Comentarii (11)

Dacă adăugarea de module dosar la PYTHONPATH nu't de lucru, puteți modifica sys.calea listă în programul dumneavoastră în cazul în care interpretorul Python căutări pentru modulele de import, piton documentația spune:

atunci Când un modul numit spam este importat, interpretul prima căutările pentru un built-in modul cu acest nume. Dacă nu a fost găsit, atunci caută un fișier numit spam.py într-o listă de directoare dat de variabila sys.calea. sys.calea este inițializat din aceste locatii:

  • directorul care conține intrare script (sau directorul curent).
  • PYTHONPATH (o listă de nume de directoare, cu aceeași sintaxă ca shell variabila PATH).
  • instalarea dependente de default.

După inițializare, Python programe pot modifica sys.calea. Directorul care conține script-ul în curs de a alerga este plasat la începutul calea de căutare, înainte de standard library cale. Acest lucru înseamnă că script-uri în acel director vor fi încărcate în loc de module cu același nume în bibliotecă director. Aceasta este o eroare dacă înlocuirea este destinat.

Știind acest lucru, puteți face următoarele în program:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft
Comentarii (3)

Puteți utiliza sistemul de OPERARE în funcție de calea de în "modul calea de căutare", care este listat în sys.calea . Astfel încât să puteți adăuga cu ușurință directorul părinte ca urmare

import sys
sys.path.insert(0,'..')

Dacă doriți să adăugați părinte-părinte director,

sys.path.insert(0,'../..')
Comentarii (1)

Don't știu prea multe despre python 2.
În python 3, folderul părinte poate fi adăugat după cum urmează:

import sys 
sys.path.append('..')

...și apoi unul este capabil de a importa module de ea

Comentarii (1)

Aici este un răspuns care's simplu astfel încât să puteți vedea cum funcționează, mici și cross-platform. Se folosește numai built-in module (os, sys și inspecta), astfel încât ar trebui să funcționeze pe orice sistem de operare (OS), deoarece Python este conceput pentru asta.

Mai scurt cod de răspuns - mai puține linii și variabile

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module  # Replace "my_module" here with the module name.
sys.path.pop(0)

Pentru mai puține linii decât asta, inlocuieste al doilea rand cu import de operare.drumul ca drumul, sys, pentru a inspecta, adaugainspecta.la începutgetsourcefile` (linia 3) și scoateți prima linie.

  • cu toate acestea acest lucru, toate importurile de module, astfel încât ar putea avea nevoie de mai mult timp, memorie și resurse.

Codul de răspunsul meu (versiune mai)

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Replace "my_module" here with the module name.

Se folosește un exemplu dintr-un Stack Overflow răspuns Cum a face I a lua calea de curent fisier executat în Python? pentru a găsi sursa (numele fișierului) din codul cu un built-in instrument.

de a inspecta import getsourcefile de la sistemul de operare.calea de import abspath Următor, ori de câte ori doriți să găsiți fișierul sursă din folosești:

abspath(getsourcefile(lambda:0))

Codul meu adaugă o cale de fișier pentru a sys.calea, la calea python lista pentru că aceasta permite Python pentru a importa module din acel folder.

După ce importați un modul în codul, l's o idee bună pentru a rula sys.calea.pop(0) pe o linie nouă când a adăugat folder are un modul cu același nume ca și un alt modul care este importat mai târziu în program. Aveți nevoie pentru a elimina elementul din listă adăugat înainte de import, nu pe alte căi. Dacă programul nu't import alte module, l's în condiții de siguranță pentru a nu șterge calea de fișier pentru după un program se termină (sau repornirea Python shell), orice modificări făcute la sys.calea să dispară.

Note despre un nume de variabilă

Răspunsul meu nu - 't de a folosi __file__ variabile pentru a obține fișierul cale/nume de funcționare codul pentru utilizatorii de aici au adesea descris ca de încredere. Nu ar trebui't folosi pentru importul de module de la folderul părinte în programe utilizate de către alte persoane.

Unele exemple în cazul în care nu't de lucru (citat din acest Stack Overflow intrebare):

• l't fi]3 găsite pe unele platforme • uneori e't toată calea de fișier

  • py2exe nu't au o __file__ atribut, dar nu este o soluție
  • atunci Când rulați la RALANTI cu execute() nu există niciofile` atribut
  • OS X 10.6 în cazul în care am NameError: nume global 'file' nu este definit`
Comentarii (5)

Aici este mai mult o soluție generală care include directorul părinte în sys.calea (funcționează pentru mine):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
Comentarii (3)

Am găsit următoarele fel de lucrări pentru importul unui pachet de script's parent directory. În exemplu, aș dori să importe funcții în env.py din `app.db pachetului.

. └── my_application └── alambic └── env.py └── app ă── __init__.py └── db

import os import sys currentdir = os.calea.dirname(os.calea.căilor(__file__)) parentdir = os.calea.dirname(currentdir) sys.calea.append(parentdir)

Comentarii (2)

Pentru mine cel mai scurt timp și preferata mea oneliner pentru accesul la directorul părinte este:

sys.path.append(os.path.dirname(os.getcwd()))

sau:

sys.path.insert(1, os.path.dirname(os.getcwd()))

sistem de operare.getcwd() întoarce numele directorul curent de lucru, sistem de operare.calea.dirname(directory_name) returnează numele directorului pentru trecut-o.

De fapt, în opinia mea Python proiect arhitectura ar trebui să fie făcut la fel în cazul în care nu există un modul de copil director va folosi orice modul din directorul părinte. Dacă se întâmplă așa ceva merită să regândească despre proiect copac.

O altă modalitate este de a adăuga directorul părinte să PYTHONPATH sistem de variabila de mediu.

Comentarii (2)

import sys sys.calea.adăugați('../')

Comentarii (1)

Atunci când nu este într-un pachet mediu cu `init.py fișierele de pathlib bibliotecă (inclus cu >= Python 3.4) face foarte concis și intuitiv pentru a adăuga calea de la directorul părinte la PYTHONPATH:

import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))
Comentarii (1)

Mai sus menționat soluții sunt, de asemenea, bine. O altă soluție la această problemă este

Dacă doriți să importați orice, de la nivelul de sus al directorului. Apoi,

from ...module_name import *

De asemenea, dacă doriți să importați orice modul din directorul părinte. Apoi,

from ..module_name import *

De asemenea, dacă doriți să importați orice modul din directorul părinte. Apoi,

from ...module_name.another_module import *

În acest fel puteți importa orice metodă specială, dacă doriți să.

Comentarii (1)

același tip de stil ca trecutul răspuns - dar în mai puține linii :P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

fișier returnează locația în care vă sunt de lucru în

Comentarii (7)

De lucru cu bibliotecile. Face o bibliotecă numită peniță, instalați-o folosind setup.py, lăsați-l să locuiască în site-ul de pachete și problemele tale sunt rezolvate. Nu't nevoie, tot ce ai face într-un singur pachet. Rupe-l în bucăți.

Comentarii (1)

Într-o Jupyter Notebook-uri cu Linux

Atâta timp cât're de lucru într-un Jupyter Notebook, această soluție pe termen scurt ar putea fi utile:

%cd ..
import nib

Acesta funcționează chiar și fără o `init.py dosarul lui.

Comentarii (0)

Într-un sistem Linux, puteți crea un soft link-ul de la "viata" folder de nib.py fișierul. Apoi, puteți pur și simplu importa, cum ar fi:

import nib
Comentarii (0)

Soluție simplă pentru calea absolută în windows 10:

import sys
sys.path.insert(0,'C:\\Users\\user01\\Desktop\\pipeline')
from folder1.folder2.filename import function_name

acest lucru va import funcția de "function_name" de la: C:\Users\user01\Desktop\pipeline\folder1\folder2\filename

Comentarii (0)