Não consigo fazer o Python importar um módulo em uma subpasta. Recebo o erro quando tento criar uma instância da classe do módulo importado, mas a importação em si é bem-sucedida. Aqui está minha estrutura de diretório:
Server
-server.py
-Models
--user.py
Aqui está o conteúdo 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
E 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)
O erro é: AttributeError: o objeto 'módulo' não tem atributo 'Usuário'
Respostas:
Acredito que você precise criar um arquivo chamado
__init__.py
no diretório Models para que o python o trate como um módulo.Então você pode fazer:
Você pode incluir o código no
__init__.py
(por exemplo, código de inicialização que algumas classes diferentes precisam) ou deixá-lo em branco. Mas deve estar lá.fonte
Você tem que criar
__init__.py
naModels
subpasta. O arquivo pode estar vazio. Ele define um pacote.Então você pode fazer:
Leia tudo sobre isso no tutorial de python, aqui .
Também há um bom artigo sobre organização de arquivos de projetos Python aqui .
fonte
Por causa da falta de __init__ mencionada acima, você esperaria um ImportError que tornaria o problema mais claro.
Você não recebe um porque 'usuário' também é um módulo existente na biblioteca padrão. Sua instrução import pega aquele e tenta encontrar a classe User dentro dele; isso não existe e só então você obterá o erro.
Geralmente é uma boa ideia tornar sua importação absoluta:
para evitar esse tipo de ambigüidade. Na verdade, a partir do Python 2.7, 'importar usuário' não parecerá de forma alguma relativo ao módulo atual.
Se você realmente deseja importações relativas, pode tê-las explicitamente no Python 2.5 e superior usando a sintaxe um tanto feia:
fonte
A maneira certa de importar um módulo localizado em uma pasta pai, quando você não tem uma estrutura de pacote padrão, é:
(você pode mesclar as duas últimas linhas, mas desta forma é mais fácil de entender).
Esta solução é multiplataforma e geral o suficiente para não precisar ser modificada em outras circunstâncias.
fonte
Você está perdendo __init__.py. Do tutorial Python:
Coloque um arquivo vazio chamado __init__.py em seu diretório de Modelos, e tudo deve ser dourado.
fonte
como você escreve os parâmetros
os.path.dirname
.... comando?fonte
Minha maneira preferida é ter __init__.py em cada diretório que contém módulos que são usados por outros módulos e, no ponto de entrada, substituir sys.path conforme abaixo:
Isso torna os arquivos em diretórios especificados visíveis para importação e posso importar o usuário de Server.py.
fonte
Depois de analisar as respostas dadas por esses contribuidores acima - Zorglub29, Tom, Mark, Aaron McMillin, lucasamaral, JoeyZhao, Kjeld Flarup, Procyclinsur, martin.zaenker, tooty44 e depurando o problema que estava enfrentando, descobri um caso de uso diferente devido para o qual eu estava enfrentando esse problema. Portanto, adiciono minhas observações abaixo para referência de qualquer pessoa.
No meu código, tive uma importação cíclica de classes. Por exemplo:
Recebi o seguinte erro quando tentei executar python -m pytest tests / test_utilities.py para executar UTs escritos em test_utilities.py.
A maneira como resolvi o erro foi refatorando meu código para mover a funcionalidade na classe de importação cíclica para que eu pudesse remover a importação cíclica de classes.
Observe, eu tenho o
__init__.py
arquivo na minha pasta ' src ', bem como na pasta ' testes ' e ainda fui capaz de me livrar do ' ImportError ' apenas reformulando o código.O seguinte link stackoverflow fornece muito mais detalhes sobre a dependência circular em Python .
fonte