Come importare la classe nella stessa directory o sottodirectory?


676

Ho una directory che memorizza tutti i file .py .

bin/
   main.py
   user.py # where class User resides
   dir.py # where class Dir resides

Voglio utilizzare le classi da user.py e dir.py in main.py .
Come posso importare queste classi Python in main.py ?
Inoltre, come posso importare la classe Userse user.py si trova in una sottodirectory?

bin/
    dir.py
    main.py
    usr/
        user.py


Risposte:


939

Python 2

Crea un file vuoto chiamato __init__.pynella stessa directory dei file. Ciò significherà per Python che è "ok per importare da questa directory".

Quindi fai ...

from user import User
from dir import Dir

Lo stesso vale se i file si trovano in una sottodirectory: inserire anche un __init__.pynella sottodirectory, quindi utilizzare le istruzioni di importazione regolari, con notazione punto. Per ogni livello di directory, è necessario aggiungere al percorso di importazione.

bin/
    main.py
    classes/
        user.py
        dir.py

Quindi se la directory fosse denominata "classi", allora dovresti farlo:

from classes.user import User
from classes.dir import Dir

Python 3

Come il precedente, ma prefisso il nome del modulo con un .se non si utilizza una sottodirectory:

from .user import User
from .dir import Dir

14
Se non__init__.py è vuoto, tutto ciò che è in è ciò che sarà disponibile quando si importa il pacchetto (e le cose non importate in non saranno affatto disponibili). __init__.py__init__.py
Ambra

23
Perché è __init__.pynecessario un file? Se inserisco tutti e tre i file nella stessa directory ed eseguo main.py, è in grado di farlo senza importgli altri due moduli. Cosa mi sto perdendo?
martineau,

30
Perché è così che Python identifica le directory da cui è consentito importare. La directory dello script che stai eseguendo è un'eccezione: puoi sempre importare da esso.
Ambra

20
@nbro & Amber: FWIW, penso che qualcosa di sottile sia cambiato rispetto alla __init__.pypossibilità di importare altri moduli nella stessa directory. In particolare import, gli altri moduli nella stessa directory del __init__.pyfile stesso che funzionava in Python 2.7.8, non sono riusciti in Python 3.4.1. Per risolvere il problema, ho dovuto aggiungere un prefisso a ciascuno di essi con il nome della sottodirectory e un punto (ovvero è import modulestato modificato in import subdirectory.module). Per fortuna ha funzionato ancora in Python 2.7.8 dopo averlo fatto.
martineau,

4
Posso confermare che questa soluzione non funziona più. Potresti voler correggerlo, modificarlo o eliminarlo del tutto.
Luís de Sousa

137

Ho appena appreso (grazie al commento di martineau ) che, per importare classi da file all'interno della stessa directory, ora scrivevi in ​​Python 3:

from .user import User
from .dir import Dir

8
se provo questo no ottengo il seguente errore ValueError: Attempted relative import in non-packagema l'errore scompare quando cambio afrom user import User
Korpel

Uso da .fileloader import Fileloader e ottengo ImportError: impossibile importare il nome 'Fileloader'
Frikster,

3
@Korpel: seguendo le discussioni in stackoverflow.com/questions/11536764/…, mi rendo conto che se l'importazione sopra indicata funziona o meno dipende da: [1] come viene chiamato il tuo script (come pacchetto o no) [2] dove il percorso di lavoro effettivo è quando lo esegui [3] come viene popolata la variabile di percorso del tuo ambiente di esecuzione
ecp

@Korpel: ho notato che il. prima che il nome del modulo sia richiesto solo quando è presente un file init .py, se non il file. può / deve essere omesso.
MUG4N,

40

Nel tuo main.py:

from user import Class

dove si Classtrova il nome della classe che si desidera importare.

Se vuoi chiamare un metodo di Class, puoi chiamarlo usando:

Class.method

Si noti che dovrebbe esserci un __init__.pyfile vuoto nella stessa directory.


1
Cosa fai se il modulo che stai tentando di importare non ha classi? Solo funzioni grezze? In Python 2 tutto quello che dovevo fare era 'import module'. Non funziona in Python 3, né "importa .module"
Frikster,

2
Funziona in python3 dopo aver eliminato il file __init__.py.
engineforce

14

Puoi importare il modulo e avere accesso tramite il suo nome se non vuoi mescolare funzioni e classi con le tue

import util # imports util.py

util.clean()
util.setup(4)

oppure puoi importare le funzioni e le classi nel tuo codice

from util import clean, setup
clean()
setup(4)

puoi usare wildchar * per importare tutto nel modulo in quel codice

from util import *
clean()
setup(4)

10

In python3, non__init__.py è più necessario . Se la directory corrente della console è la directory in cui si trova lo script Python, tutto funziona perfettamente

import user

Tuttavia, questo non funzionerà se chiamato da una directory diversa, che non contiene user.py.
In tal caso, utilizzare

from . import user

Funziona anche se vuoi importare l'intero file anziché solo una classe da lì.


2
Sto usando pylint nel codice vs, e ho avuto problemi con un'importazione nella stessa directory sempre contrassegnata come un errore ( import userera sottolineata in rosso); modificato al relativo import ( from . import user) e il linter non lo ha più contrassegnato.
rbatt

9

Per rendere più semplice la comprensione:

Passaggio 1: andiamo in una directory, dove tutto sarà incluso

$ cd /var/tmp

Passaggio 2: ora consente di creare un file class1.py che ha un nome di classe Class1 con un po 'di codice

$ cat > class1.py <<\EOF
class Class1:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF

Passaggio 3: ora consente di creare un file class2.py che ha un nome di classe Class2 con un po 'di codice

$ cat > class2.py <<\EOF
class Class2:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF

Passaggio 4: ora consente di creare un main.py che verrà eseguito una volta per utilizzare Class1 e Class2 da 2 file diversi

$ cat > main.py <<\EOF
"""this is how we are actually calling class1.py and  from that file loading Class1"""
from class1 import Class1 
"""this is how we are actually calling class2.py and  from that file loading Class2"""
from class2 import Class2

print Class1.OK
print Class2.OK
EOF

Passaggio 5: eseguire il programma

$ python main.py

L'output sarebbe

[Class1 OK]: 
[Class2 OK]:

4
E cosa succede se questo non funziona e main.py non riesce a leggere class1 o class2? ... Cosa ci manca?
darkgaze,

6

Python 3


Stesso directory.

importare file:log.py

classe di importazione: SampleApp().

import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

o

directory è basic.

importare nel file: log.py.

classe di importazione: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

5
from user import User 
from dir import Dir 

Questo ha funzionato per me senza avere file .py di init per Python 2.7 e Python 3.6.
imsrgadich,

1
@imsrgadich funziona fintanto che stai eseguendo python nella directory contenente i file. Questa è un'eccezione. Vedi questo commento
Ciprian Tomoiagă,

5

Se user.py e dir.py non includono le classi, allora

from .user import User
from .dir import Dir

non funziona. Dovresti quindi importare come

from . import user
from . import dir

0

Non sono sicuro del motivo per cui questo lavoro, ma usando build Pycharm from file_in_same_dir import class_name

L'IDE si è lamentato, ma sembra che abbia ancora funzionato. Sto usando Python 3.7


-2

Fin troppo breve, creare un file __init__.pyè la directory di classi e quindi importarlo nello script come segue (Importa tutti i casi)

from classes.myscript import *

Importa solo le classi selezionate

from classes.myscript import User
from classes.myscript import Dir

4
Le importazioni di caratteri jolly viste in questa risposta sono generalmente considerate stile errato come descritto in PEP 8 .
V02460,

-3

per importare dalla stessa directory

from . import the_file_you_want_to_import 

per importare dalla sottodirectory che la directory dovrebbe contenere

init .py

file diverso dai file quindi

dalla directory importare il tuo file


3
Non credo che questa risposta aggiunga qualcosa che altre risposte non hanno fatto, e inoltre non è un riassunto completo delle altre risposte. Quindi mi chiedo perché l'hai scritto
lucidbrot,

-3

python3

uso

from .user import User inside dir.py file

e

use from class.dir import Dir inside main.py
or from class.usr import User inside main.py

così


3
Questa risposta non aggiunge nulla di più rispetto all'altra risposta e non ha alcuna spiegazione. C'è un modo per modificare la tua risposta per aggiungerla o migliorarla? Perché in caso contrario, è necessario effettuare il downgrade come questa risposta è stata o rimossa del tutto.
Das_Geek il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.