¿Cómo importar la clase dentro del mismo directorio o subdirectorio?

676

Tengo un directorio que almacena todos los archivos .py .

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

Quiero usar clases de user.py y dir.py en main.py .
¿Cómo puedo importar estas clases de Python en main.py ?
Además, ¿cómo puedo importar la clase Usersi user.py está en un subdirectorio?

bin/
    dir.py
    main.py
    usr/
        user.py
Bin Chen
fuente
Consulte también las respuestas en Python: importe un archivo desde un subdirectorio .
Trilarion

Respuestas:

939

Python 2

Cree un archivo vacío llamado __init__.pyen el mismo directorio que los archivos. Eso significará para Python que está "bien importar desde este directorio".

Entonces solo haz ...

from user import User
from dir import Dir

Lo mismo es cierto si los archivos están en un subdirectorio: coloque también __init__.pyen el subdirectorio y luego use declaraciones de importación regulares, con notación de puntos. Para cada nivel de directorio, debe agregar a la ruta de importación.

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

Entonces, si el directorio se llamaba "clases", entonces haría esto:

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

Python 3

Igual que el anterior, pero prefija el nombre del módulo con un .si no está usando un subdirectorio:

from .user import User
from .dir import Dir
Ámbar
fuente
14
Si no__init__.py está vacío, lo que esté dentro es lo que estará disponible cuando importe el paquete (y las cosas no importadas no estarán disponibles en absoluto). __init__.py__init__.py
Ámbar
23
¿Por qué se __init__.pynecesita un archivo? Si pongo los tres archivos en el mismo directorio y lo ejecuto main.py, puede hacerlo importdesde los otros dos módulos sin él. ¿Qué me estoy perdiendo?
Martineau
30
Porque así es como Python identifica los directorios desde los cuales puede importar. El directorio del script que está ejecutando es una excepción: siempre puede importarlo.
Ámbar
20
@nbro & Amber: FWIW, creo que algo sutil ha cambiado con respecto a la __init__.pyposibilidad de importar otros módulos en el mismo directorio. Específicamente, imports de otros módulos en el mismo directorio que el __init__.pyarchivo mismo que funcionaba en Python 2.7.8, fallaron en Python 3.4.1. Para solucionarlo tuve que prefijar cada uno de ellos con el nombre del subdirectorio y un punto (es decir, import moduletuve que cambiarlo a import subdirectory.module). Afortunadamente, todavía funcionó en Python 2.7.8 después de hacer esto.
martineau
44
Puedo confirmar que esta solución ya no es funcional. Es posible que desee corregirlo, modificarlo o eliminarlo por completo.
Luís de Sousa
137

Acabo de enterarme (gracias al comentario de martineau ) de que, para importar clases de archivos dentro del mismo directorio, ahora escribirías en Python 3:

from .user import User
from .dir import Dir
ecp
fuente
8
si intento esto noValueError: Attempted relative import in non-packagefrom user import User
aparece
Uso de .fileloader import Fileloader import y obtengo ImportError: no puedo importar el nombre 'Fileloader'
Frikster
3
@ Korpel: Siguiendo las discusiones en stackoverflow.com/questions/11536764/…, me doy cuenta de que si la importación dada anteriormente funciona o no depende de: [1] cómo se llama su script (como paquete o no) [2] donde la ruta de trabajo real es cuando la ejecutas [3] cómo se rellena la variable de ruta de tu entorno de ejecución
ecp
@ Korpel: me di cuenta de que el. antes de que se requiera el nombre del módulo solo cuando está presente un archivo init .py, si no el. puede / debe ser omitido.
MUG4N
40

En su main.py:

from user import Class

donde Classestá el nombre de la clase que quieres importar.

Si desea llamar a un método de Class, puede llamarlo usando:

Class.method

Tenga en cuenta que debe haber un __init__.pyarchivo vacío en el mismo directorio.

usuario225312
fuente
1
¿Qué haces si el módulo que estás intentando importar no tiene clases? ¿Solo funciones en bruto? En python 2 todo lo que tenía que hacer era 'importar módulo'. No funciona en python 3, ni 'import .module'
Frikster
2
Esto funciona en python3 después de eliminar el __init__.py.
engineforce
14

Puede importar el módulo y tener acceso a través de su nombre si no desea mezclar funciones y clases con las suyas.

import util # imports util.py

util.clean()
util.setup(4)

o puede importar las funciones y clases a su código

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

puedes usar wildchar * para importar todo en ese módulo a tu código

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

En python3, __init__.pyes ya no es necesario . Si el directorio actual de la consola es el directorio donde se encuentra el script de Python, todo funciona bien con

import user

Sin embargo, esto no funcionará si se llama desde un directorio diferente, que no contiene user.py.
En ese caso, use

from . import user

Esto funciona incluso si desea importar todo el archivo en lugar de solo una clase desde allí.

lucidbrot
fuente
2
Estoy usando pylint en el código vs, y estaba teniendo problemas con una importación del mismo directorio que siempre se marcaba como un error ( import userestaba subrayado en rojo); cambió a la importación relativa ( from . import user) y la interfaz ya no la marcó.
rbatt
9

Para hacerlo más simple de entender:

Paso 1: vamos a un directorio, donde se incluirán todos

$ cd /var/tmp

Paso 2: ahora hagamos un archivo class1.py que tenga un nombre de clase Class1 con algún código

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

Paso 3: ahora hagamos un archivo class2.py que tenga un nombre de clase Class2 con algún código

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

Paso 4: ahora hagamos un main.py que se ejecutará una vez para usar Class1 y Class2 de 2 archivos diferentes

$ 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

Paso 5: ejecuta el programa

$ python main.py

La salida sería

[Class1 OK]: 
[Class2 OK]:
Hassan Nadeem
fuente
44
¿Y qué sucede si esto no funciona y main.py no puede leer class1 o class2? ... ¿qué nos estamos perdiendo?
darkgaze
6

Python 3


Mismo directory .

importar archivo:log.py

clase de importación: SampleApp().

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

o

directorio es basic .

importar en archivo: log.py .

clase de importación: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Yasith Praharshana
fuente
5
from user import User 
from dir import Dir 
demas
fuente
Esto funcionó para mí sin tener el archivo init .py para Python 2.7 y Python 3.6.
imsrgadich
1
@imsrgadich funciona siempre que esté ejecutando Python en el directorio que contiene los archivos. Esta es una excepción. Ver este comentario
Ciprian Tomoiagă
5

Si user.py y dir.py no incluyen clases, entonces

from .user import User
from .dir import Dir

no está trabajando. Luego debe importar como

from . import user
from . import dir
Andreas Foteas
fuente
0

No estoy seguro de por qué esto funciona, pero usando Pycharm build from file_in_same_dir import class_name

El IDE se quejó al respecto, pero parece que todavía funcionó. Estoy usando Python 3.7

stingMantis
fuente
-2

Demasiado breve, Crear un archivo __init__.pyes el directorio de clases y luego importarlo a su script como sigue (Importar todos los casos)

from classes.myscript import *

Importar solo clases seleccionadas

from classes.myscript import User
from classes.myscript import Dir
Shafiq
fuente
44
Las importaciones de comodines, como se ve en esta respuesta, generalmente se consideran mal estilo como se describe en PEP 8 .
V02460
-3

importar desde el mismo directorio

from . import the_file_you_want_to_import 

para importar desde el subdirectorio, el directorio debe contener

init .py

archivo que no sean sus archivos entonces

desde el directorio import your_file

rojo_hlerr
fuente
3
No creo que esta respuesta agregue nada que otras respuestas no hayan agregado, y tampoco es un resumen exhaustivo de las otras respuestas. Así que me pregunto por qué lo escribiste
Lucidbrot
-3

Python3

utilizar

from .user import User inside dir.py file

y

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

al igual que

icharis
fuente
3
Esta respuesta realmente no agrega nada más que la otra respuesta ya lo hace, y no tiene explicación. ¿Hay alguna forma de editar su respuesta para agregarla o mejorarla? Porque de lo contrario, es probable que se rechace como si esta respuesta fuera eliminada por completo.
Das_Geek