Comment importer la classe dans le même répertoire ou sous-répertoire?

676

J'ai un répertoire qui stocke tous les fichiers .py .

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

Je veux utiliser des classes de user.py et dir.py dans main.py .
Comment puis-je importer ces classes Python dans main.py ?
De plus, comment puis-je importer une classe Usersi user.py est dans un sous-répertoire?

bin/
    dir.py
    main.py
    usr/
        user.py
Bin Chen
la source

Réponses:

939

Python 2

Créez un fichier vide appelé __init__.pydans le même répertoire que les fichiers. Cela signifiera à Python qu'il est "correct d'importer depuis ce répertoire".

Alors fais juste ...

from user import User
from dir import Dir

Il en va de même si les fichiers se trouvent dans un sous-répertoire - mettez également un __init__.pydans le sous-répertoire, puis utilisez des instructions d'importation régulières, avec la notation par points. Pour chaque niveau de répertoire, vous devez ajouter au chemin d'importation.

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

Donc, si le répertoire était nommé "classes", alors vous feriez ceci:

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

Python 3

Identique à la précédente, mais préfixez le nom du module avec a .si vous n'utilisez pas de sous-répertoire:

from .user import User
from .dir import Dir
ambre
la source
14
Si __init__.pyn'est pas vide, alors ce qui est dedans est __init__.pyce qui sera disponible lorsque vous importerez le paquet (et les choses non importées __init__.pyne seront pas disponibles du tout).
Ambre
23
Pourquoi un __init__.pyfichier est-il nécessaire? Si je mets les trois fichiers dans le même répertoire et que main.pyje l' exécute , il est capable de importpartir des deux autres modules sans lui. Qu'est-ce que je rate?
martineau
30
Parce que c'est ainsi que Python identifie les répertoires à partir desquels vous êtes autorisé à importer. Le répertoire du script que vous exécutez est une exception - vous êtes toujours autorisé à en importer.
Amber
20
@nbro & Amber: FWIW, je pense que quelque chose de subtil a changé en ce qui concerne __init__.pyet pouvoir importer d'autres modules dans le même répertoire. Plus précisément, importles autres modules du même répertoire que le __init__.pyfichier lui-même qui fonctionnait dans Python 2.7.8, ont échoué dans Python 3.4.1. Pour le corriger, j'ai dû préfixer chacun d'eux avec le nom du sous-répertoire et un point (c'est import module-à- dire qu'il fallait le changer import subdirectory.module). Heureusement, cela fonctionnait toujours dans Python 2.7.8 après avoir fait cela.
martineau
4
Je peux confirmer que cette solution n'est plus fonctionnelle. Vous pouvez le corriger, l'amender ou le supprimer purement et simplement.
Luís de Sousa
137

Je viens d'apprendre (grâce au commentaire de martineau ) que, pour importer des classes à partir de fichiers dans le même répertoire, vous écririez maintenant en Python 3:

from .user import User
from .dir import Dir
ecp
la source
8
si j'essaye non, j'obtiens l'erreur suivante ValueError: Attempted relative import in non-packagemais l'erreur disparaît quand je passe àfrom user import User
Korpel
J'utilise depuis .fileloader import Fileloader et j'obtiens ImportError: impossible d'importer le nom 'Fileloader'
Frikster
3
@Korpel: Suite aux discussions dans stackoverflow.com/questions/11536764/… je me rends compte que si l'importation donnée ci-dessus fonctionne ou non dépend de: [1] comment votre script est appelé (en tant que package ou non) [2] où le chemin de travail réel est lorsque vous l'exécutez [3] comment la variable de chemin de votre environnement d'exécution est remplie
ecp
@Korpel: J'ai remarqué que le. avant le nom du module n'est requis que lorsqu'un fichier init .py est présent, sinon le. peut / doit être omis.
MUG4N
40

Dans votre main.py:

from user import Class

Classest le nom de la classe que vous souhaitez importer.

Si vous voulez appeler une méthode de Class, vous pouvez l'appeler en utilisant:

Class.method

Notez qu'il devrait y avoir un __init__.pyfichier vide dans le même répertoire.

user225312
la source
1
Que faites-vous si le module que vous essayez d'importer n'a pas de classes? Juste des fonctions brutes? En python 2, je n'avais qu'à «importer le module». Ne fonctionne pas en python 3, ni 'import .module'
Frikster
2
Cela fonctionne en python3 après avoir supprimé le __init__.py.
engineforce
14

Vous pouvez importer le module et y accéder par son nom si vous ne voulez pas mélanger les fonctions et les classes avec les vôtres

import util # imports util.py

util.clean()
util.setup(4)

ou vous pouvez importer les fonctions et les classes dans votre code

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

vous pouvez utiliser wildchar * pour importer tout dans ce module dans votre code

from util import *
clean()
setup(4)
A.Zaben
la source
10

En python3, __init__.pyest plus nécessaire . Si le répertoire actuel de la console est le répertoire où se trouve le script python, tout fonctionne bien avec

import user

Cependant, cela ne fonctionnera pas s'il est appelé à partir d'un répertoire différent, qui ne contient pas user.py.
Dans ce cas, utilisez

from . import user

Cela fonctionne même si vous souhaitez importer le fichier entier au lieu d'une simple classe à partir de là.

lucidbrot
la source
2
J'utilise pylint dans le code vs et rencontrais des problèmes avec une importation du même répertoire toujours signalée comme une erreur (a import userété soulignée en rouge); changé en import relatif ( from . import user) et le linter ne l'a plus signalé.
rbatt
9

Pour le rendre plus simple à comprendre:

Étape 1: permet d'accéder à un répertoire, où tout sera inclus

$ cd /var/tmp

Étape 2: permet maintenant de créer un fichier class1.py qui a un nom de classe Class1 avec du code

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

Étape 3: permet maintenant de créer un fichier class2.py qui a un nom de classe Class2 avec du code

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

Étape 4: permet maintenant de créer un fichier main.py qui sera exécuté une fois pour utiliser Class1 et Class2 à partir de 2 fichiers différents

$ 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

Étape 5: exécutez le programme

$ python main.py

La sortie serait

[Class1 OK]: 
[Class2 OK]:
Hassan Nadeem
la source
4
Et que se passe-t-il si cela ne fonctionne pas et que main.py ne peut pas lire classe1 ou classe2? ... qu'est-ce qui nous manque?
darkgaze
6

Python 3


Pareil directory.

Importer le fichier:log.py

classe d'importation: SampleApp().

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

ou

répertoire est basic.

importer dans le fichier: log.py.

classe d'importation: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Yasith Praharshana
la source
5
from user import User 
from dir import Dir 
demas
la source
Cela a fonctionné pour moi sans avoir de fichier init .py pour Python 2.7 et Python 3.6.
imsrgadich
1
@imsrgadich cela fonctionne tant que vous exécutez python dans le répertoire contenant les fichiers. Ceci est une exception. Voir ce commentaire
Ciprian Tomoiagă
5

Si user.py et dir.py n'incluent pas les classes, alors

from .user import User
from .dir import Dir

ne fonctionne pas. Vous devez ensuite importer en tant que

from . import user
from . import dir
Andreas Foteas
la source
0

Je ne sais pas pourquoi cela fonctionne, mais en utilisant la construction Pycharm from file_in_same_dir import class_name

L'IDE s'en est plaint, mais il semble que cela fonctionne toujours. J'utilise Python 3.7

stingMantis
la source
-2

Tout simplement trop bref, créer un fichier __init__.pyest le répertoire des classes, puis l'importer dans votre script comme suit (Importer tous les cas)

from classes.myscript import *

Importer uniquement les classes sélectionnées

from classes.myscript import User
from classes.myscript import Dir
Shafiq
la source
4
Les importations de caractères génériques comme indiqué dans cette réponse sont généralement considérées comme un mauvais style, comme décrit dans PEP 8 .
V02460
-3

importer depuis le même répertoire

from . import the_file_you_want_to_import 

pour importer à partir du sous-répertoire, le répertoire doit contenir

init .py

déposer autre que vous fichiers puis

à partir du répertoire, importez votre_fichier

rojo_hlerr
la source
3
Je ne pense pas que cette réponse ajoute quelque chose que les autres réponses n'ont pas fait, et n'est pas non plus un résumé complet des autres réponses. Je me demande donc pourquoi vous l'avez écrit
lucidbrot
-3

Python3

utilisation

from .user import User inside dir.py file

et

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

ainsi

icharis
la source
3
Cette réponse n'ajoute vraiment rien de plus que l'autre réponse, et n'a aucune explication. Existe-t-il un moyen de modifier votre réponse pour l'ajouter ou l'améliorer? Parce qu'autrement, cela risque d'être rejeté comme cette réponse a été ou complètement supprimé.
Das_Geek