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

Erro:

Pessoal, para quem estiver com este problema ao executar a seguinte rotina:

print(restaurante_praca.media_avaliacoes())

A solução que encontrei foi super estranha mas para mim foi o que corrigiu o problema. Apenas comentar o @property, ou seja, não utiliza-lo.

Antes:

     @property
    def media_avaliacoes(self):
        if not self._avaliacao:
            return 0
        soma_das_notas = sum(avaliacao._nota for avaliacao in self._avaliacao)
        quantidade_de_notas = len(self._avaliacao)
        media = round(soma_das_notas / quantidade_de_notas, 1)
        return media

Depois:

    # @property
    def media_avaliacoes(self):
        if not self._avaliacao:
            return 0
        soma_das_notas = sum(avaliacao._nota for avaliacao in self._avaliacao)
        quantidade_de_notas = len(self._avaliacao)
        media = round(soma_das_notas / quantidade_de_notas, 1)
        return media
3 respostas

Olá, Marcio.

Tudo bem?

Legal que você encontrou uma solução para o problema comentando o @property do método media_avaliacoes. No entanto, isso pode ser um indicativo de que há algo mais acontecendo no seu código que precisa ser ajustado.

O uso do @property é útil para acessar métodos como se fossem atributos, o que pode tornar o código mais legível e intuitivo. Vamos tentar entender o que pode estar causando o problema.

Aqui estão algumas coisas que você pode verificar:

  1. Nome do Atributo: Certifique-se de que o nome do atributo _avaliacao está correto e que ele é inicializado corretamente no construtor da classe Restaurante.

  2. Instância da Classe: Verifique se a instância restaurante_praca está sendo criada corretamente e se as avaliações estão sendo adicionadas antes de chamar o método media_avaliacoes.

  3. Acesso ao Método: Quando você usa @property, você deve acessar o método sem parênteses. Por exemplo:

    print(restaurante_praca.media_avaliacoes)
    

    Se você usar parênteses, estará tentando chamar o método diretamente, o que pode causar um erro.

Vamos revisar o código com o @property aplicado corretamente:

class Restaurante:
    def __init__(self, nome, categoria):
        self.nome = nome
        self.categoria = categoria
        self._avaliacao = []

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

    @property
    def media_avaliacoes(self):
        if not self._avaliacao:
            return 0
        soma_das_notas = sum(avaliacao._nota for avaliacao in self._avaliacao)
        quantidade_de_notas = len(self._avaliacao)
        media = round(soma_das_notas / quantidade_de_notas, 1)
        return media

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

# Exemplo de uso
restaurante_praca = Restaurante('praça', 'Gourmet')
restaurante_praca.receber_avaliacao('Gui', 10)
restaurante_praca.receber_avaliacao('Lais', 8)
restaurante_praca.receber_avaliacao('Emy', 5)

print(restaurante_praca.media_avaliacoes)  # Sem parênteses

Certifique-se de que está acessando media_avaliacoes sem parênteses. Isso deve resolver o problema sem precisar comentar o @property.

Espero ter ajudado. Qualquer dúvida manda aqui. Bons estudos.

Verdade Renan. Percebi que para utilizar o método com parenteses (chamando diretamente o método):

print(restaurante_praca.media_avaliacoes())

Foi necessário comentar o @property tendo a seguinte saída:

Nome do restaurante       | Categoria                 | Avaliação                 | Status
Praça                     | GOURMET                   | 5.0                       | ☐
Mexican Food              | MEXICANA                  | -                         | ⌧
Japa                      | JAPONESA                  | -                         | ☐

Caso contrário sem comentar o @property temos que retirar os parenteses do método para que funcione este retorno (Neste caso uma boa prática pelo que entendi):

print(restaurante_praca.media_avaliacoes)

Dessa forma teremos a mesma saída acima. Entendi certo?

Já te agradeço.

solução!

Olá, Marcio.

Sim, você entendeu corretamente! Vamos esclarecer alguns pontos para reforçar o conceito:

Uso de @property

Quando você utiliza o decorador @property em um método de uma classe, você transforma aquele método em um "atributo calculado". Isso significa que você pode acessar o resultado do método como se fosse um atributo, sem a necessidade de usar parênteses.

Sem @property

# Sem o @property, você precisa chamar o método com parênteses
print(restaurante_praca.media_avaliacoes())

Com @property

# Com o @property, você acessa o método como um atributo, sem parênteses
print(restaurante_praca.media_avaliacoes)

Benefícios de Usar @property

  • Legibilidade: O código fica mais intuitivo e legível, já que você acessa o método como se fosse um atributo.
  • Encapsulamento: Permite calcular o valor de um atributo dinamicamente, mas ainda oferece a aparência de um atributo simples.

Exemplo Completo

Aqui está um exemplo completo para ilustrar:

class Restaurante:
    def __init__(self, nome, categoria):
        self.nome = nome
        self.categoria = categoria
        self._avaliacao = []

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

    @property
    def media_avaliacoes(self):
        if not self._avaliacao:
            return 0
        soma_das_notas = sum(avaliacao._nota for avaliacao in self._avaliacao)
        quantidade_de_notas = len(self._avaliacao)
        media = round(soma_das_notas / quantidade_de_notas, 1)
        return media

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

# Exemplo de uso
restaurante_praca = Restaurante('Praça', 'Gourmet')
restaurante_praca.receber_avaliacao('Gui', 10)
restaurante_praca.receber_avaliacao('Lais', 8)
restaurante_praca.receber_avaliacao('Emy', 5)

# Usando o @property, acessa-se como um atributo
print(restaurante_praca.media_avaliacoes)  # Sem parênteses

# Saída esperada: 7.7

Resumo

  • Com @property: Acesse como um atributo (sem parênteses).
  • Sem @property: Chame como um método (com parênteses).

Sua observação está correta: utilizar @property é uma boa prática porque melhora a legibilidade do código e mantém o princípio de encapsulamento.

Espero que isso tenha esclarecido suas dúvidas! Se tiver mais perguntas, sinta-se à vontade para perguntar.

Bons estudos!