Parece que no puedo hacer que Python importe un módulo en una subcarpeta. Recibo el error cuando intento crear una instancia de la clase desde el módulo importado, pero la importación en sí se realiza correctamente. Aquí está mi estructura de directorio:
Server
-server.py
-Models
--user.py
Aquí está el contenido de server.py:
from sys import path
from os import getcwd
path.append(getcwd() + "\\models") #Yes, i'm on windows
print path
import user
u=user.User() #error on this line
Y user.py:
class User(Entity):
using_options(tablename='users')
username = Field(String(15))
password = Field(String(64))
email = Field(String(50))
status = Field(Integer)
created = Field(DateTime)
El error es: AttributeError: el objeto 'módulo' no tiene atributo 'Usuario'
Respuestas:
Creo que necesita crear un archivo llamado
__init__.py
en el directorio Modelos para que Python lo trate como un módulo.Entonces puedes hacer:
from Models.user import User
Puede incluir código en el
__init__.py
(por ejemplo, el código de inicialización que necesitan algunas clases diferentes) o dejarlo en blanco. Pero debe estar ahí.fuente
Tienes que crear
__init__.py
en laModels
subcarpeta. El archivo puede estar vacío. Define un paquete.Entonces puedes hacer:
from Models.user import User
Lea todo sobre esto en el tutorial de Python, aquí .
También hay un buen artículo sobre la organización de archivos de proyectos de Python aquí .
fuente
Debido a la falta de __init__ mencionada anteriormente, esperaría un ImportError que aclararía el problema.
No obtiene uno porque 'usuario' también es un módulo existente en la biblioteca estándar. Su declaración de importación toma ese e intenta encontrar la clase de usuario dentro de él; que no existe y solo entonces aparece el error.
Por lo general, es una buena idea hacer que su importación sea absoluta:
import Server.Models.user
para evitar este tipo de ambigüedad. De hecho, desde Python 2.7, el 'usuario de importación' no se verá en relación con el módulo actual en absoluto.
Si realmente desea importaciones relativas, puede tenerlas explícitamente en Python 2.5 y versiones posteriores usando la sintaxis algo fea:
from .user import User
fuente
La forma correcta de importar un módulo ubicado en una carpeta principal, cuando no tiene una estructura de paquete estándar, es:
import os, sys CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.dirname(CURRENT_DIR))
(puede fusionar las dos últimas líneas, pero de esta manera es más fácil de entender).
Esta solución es multiplataforma y es lo suficientemente general como para no necesitar modificaciones en otras circunstancias.
fuente
Falta __init__.py. Del tutorial de Python:
Coloque un archivo vacío llamado __init__.py en su directorio de Modelos, y todo debería ser dorado.
fuente
¿Cómo se escribe el
os.path.dirname
comando parámetros ....?import os, sys CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.dirname(CURRENT_DIR))
fuente
Mi forma preferida es tener __init__.py en cada directorio que contiene módulos que son utilizados por otros módulos, y en el punto de entrada, anular sys.path como se muestra a continuación:
def get_path(ss): return os.path.join(os.path.dirname(__file__), ss) sys.path += [ get_path('Server'), get_path('Models') ]
Esto hace que los archivos en directorios especificados sean visibles para su importación, y puedo importar usuarios desde Server.py.
fuente
Después de revisar las respuestas dadas por estos colaboradores anteriores: Zorglub29, Tom, Mark, Aaron McMillin, lucasamaral, JoeyZhao, Kjeld Flarup, Procyclinsur, martin.zaenker, tooty44 y depurar el problema al que me enfrentaba, descubrí un caso de uso diferente debido a lo que estaba enfrentando este problema. Por lo tanto, agrego mis observaciones a continuación para referencia de cualquiera.
En mi código tenía una importación cíclica de clases. Por ejemplo:
src |-- utilities.py (has Utilities class that uses Event class) |-- consume_utilities.py (has Event class that uses Utilities class) |-- tests |-- test_consume_utilities.py (executes test cases that involves Event class)
Recibí el siguiente error cuando intenté ejecutar python -m pytest tests / test_utilities.py para ejecutar UT escritas en test_utilities.py.
ImportError while importing test module '/Users/.../src/tests/test_utilities.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: tests/test_utilities.py:1: in <module> from utilities import Utilities ... ... E ImportError: cannot import name 'Utilities'
La forma en que resolví el error fue re-factorizando mi código para mover la funcionalidad en la clase de importación cíclica para poder eliminar la importación cíclica de clases.
Tenga en cuenta que tengo un
__init__.py
archivo en mi carpeta ' src ', así como en la carpeta ' tests ' y aún así pude deshacerme del ' ImportError ' simplemente volviendo a factorizar el código.El siguiente enlace de stackoverflow proporciona muchos más detalles sobre la dependencia circular en Python .
fuente