Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

[Bug] Erros de importação

Meu código está dando erro ao executar,

A estrutura de pastas no momento está:

OO-SABOR-EXPRESS/

├── app.py

└── modelos/ ├── avaliacao.py └── restaurante.py

código em avaliacao.py:

class Avaliacao:
    def __init__(self, cliente, nota):
        self._cliente = cliente
        self._nota = nota

código em restaurante.py

from modelos.avaliacao import Avaliacao

class Restaurante:
    restaurantes = []

    def __init__(self, nome, categoria):
        self._nome = nome.title()
        self._categoria = categoria.upper()
        self._ativo = False
        self._avaliacao = []
        Restaurante.restaurantes.append(self)
    
    def __str__(self):
        return f'{self._nome} | {self._categoria}'
    
    @classmethod
    def listar_restaurantes(cls):
        print(f'{'Nome do restaurante'.ljust(25)} | {'Categoria'.ljust(25)} | {'Avaliação'.ljust(25)} | {'Status'}')
        for restaurante in cls.restaurantes:
            print(f'{restaurante._nome.ljust(25)} | {restaurante._categoria.ljust(25)} | {restaurante.media_avaliacoes} | {restaurante.ativo}')

    @property
    def ativo(self):
        return '⌧' if self._ativo else '☐'
    
    def alternar_estado(self):
        self._ativo = not self._ativo4

    def receber_avaliacao(self, cliente, nota):
        avaliacao = Avaliacao(cliente, nota)
        self._avaliacao.append(avaliacao)

    @property
    def media_avaliacoes(self):
        if not self._avaliacao:
            return 'Sem avaliações'
        soma_das_notas = sum(avaliacao._notas for avaliacao in self._avaliacao)
        quantidade_de_notas = len(self._avaliacao)
        media = round(soma_das_notas / quantidade_de_notas, 1)
        return media

código em app.py:

from modelos.restaurante import Restaurante

restaurante_Plaza = Restaurante('Plaza', 'Gourmet')
restaurante_Plaza.receber_avaliacao('Vinicius', 9)
restaurante_Plaza.receber_avaliacao('Nerdola', 5)
restaurante_Plaza.receber_avaliacao('Ferreira', 11)

restaurante_mexicano = Restaurante('Chicos', 'Mexicano')
restaurante_formula = Restaurante('F1 Foods', 'Tematico')

restaurante_mexicano.alternar_estado()

def main():
    Restaurante.listar_restaurantes()

if __name__ == '__main__':
    main()

Erro ao executar o app.py:

Traceback (most recent call last): File "D:- Arquivos Pessoais\Cursos, Estudos, Música e Desenhos\Alura\Python\curso-python-2-aula_3\OO-SABOR-EXPRESS\app.py", line 1, in from modelos.restaurante import Restaurante File "D:- Arquivos Pessoais\Cursos, Estudos, Música e Desenhos\Alura\Python\curso-python-2-aula_3\OO-SABOR-EXPRESS\modelos\restaurante.py", line 1, in from modelos.avaliacao import Avaliacao ImportError: cannot import name 'Avaliacao' from 'modelos.avaliacao' (D:- Arquivos Pessoais\Cursos, Estudos, Música e Desenhos\Alura\Python\curso-python-2-aula_3\OO-SABOR-EXPRESS\modelos\avaliacao.py)

4 respostas

Oi Vinicius, pelo que vc mostrou na estrutura, os scripts avaliacao.py e restaurante.py estão na mesma pasta. Então quando vc tenta fazer from modelos.avaliacao import Avaliacao, vc está tentando acessar uma pasta modelos na pasta em que restaurante.py está e não da pasta acima onde o script app é executado.

No script restaurante.py mude o import para apenas from avaliacao import Avaliacao

De fato o problema se encontrava exatamente nessa importação, porém somente retirar o modelos. não foi o suficiente, utililzei o blackbox.ai pra me ajudar e ele me disse a seguinte resposta:

Uma solução para esse problema é usar uma importação relativa. Em vez de from avaliacao import Avaliacao, você pode usar from .avaliacao import Avaliacao no arquivo restaurante.py. O ponto (.) indica que o módulo avaliacao está no mesmo pacote que o arquivo restaurante.py.

Além disso ele comenta que é melhor o uso de importações absolutas ao invés de relativas, e disse que o melhor meio seria:

import sys
sys.path.insert(0, 'modelos')

from modelos.restaurante import Restaurante

Digamos que consegui solucionar, mas essa questão de diretório ainda me deixa um pouco confuso, não é tão simples quanto importar do CSS, HTML pro Javascript ou sou eu que to dificultando as coisas mesmo?

solução!

Oi Vinicius, vc está certo quanto ao ponto ali no import, precisa ter se for fazer o caminho relativo, sem o ponto seria se vc fosse rodar o restaurante.py diretamente. Ai como vi que ainda teve problema, eu só copiei o código de cada um dos arquivos que vc colocou aqui no post e rodei, e funcionou certo (precisei apenas ajustar um caractere digitado a mais e aspas em uma linha, mas não precisei alterar mais nada além disso).

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Então fiquei na dúvida, a partir de onde exatamente vc está executando o código? Seu terminal está na pasta OO-SABOR-EXPRESS ?

Quanto a importação, deveria sim ser direto como está pensando, vc pode ter problemas quando um módulo que criar tiver o mesmo nome que algum já existente no seu projeto ou que o python já tem por padrão, mas modelos não é um que daria problema.

Quanto a esse trecho de código tome cuidado.

import sys
sys.path.insert(0, 'modelos')

O interpretador do python carrega os módulos na ordem que os encontra no projeto e modificar essa ordem pode acabar introduzindo bugs na execução. Recomendo pesquisar antes sobre alterar a ordem de importação e ter certeza antes de inserir isso em mais códigos que criar.

Eu não sei dizer se esse era o problema, porém minha pasta onde fica toda documentação de estudo da Alura, está dentro de um HD que fica em constante upload em nuvem, após realizar a desativação do upload ao vivo da pasta de estudos, esse tipo de erro de import acabou não ocorrendo mais, se foi isso mesmo que solucionou, nunca saberei, mas sua respostas me ajudou bastante a entender o que pode ocorrer também! Obrigado