Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Ordenação de lista de objetos - 'property' object is not callable

Boa tarde, pessoal!

Após a leitura do artigo Ordenando listas no Python (https://www.alura.com.br/artigos/ordenando-listas-no-python), criei o código abaixo para ordenar os objetos de uma lista de produtos.

Abaixo, segue o código que funcionou sem erros:

class Produto:

    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco

    def get_nome(self):
        return self.nome

    def get_preco(self):
        return self.preco

    def __str__(self):
        return ("Nome: {} | Preco: R$ {:.2f}".format(self.nome, self.preco))

    def __iter__(self):
        pass


produto_01 = Produto("Arroz", 20.90)
produto_02 = Produto("Feijao", 10.90)
produto_03 = Produto("Alface", 5.10)
produto_04 = Produto("Tomate", 4.90)
produto_05 = Produto("Cebola", 1.00)

lista_produtos = [produto_01, produto_02, produto_03, produto_04, produto_05]

print("==Lista de produtos sem ordenacao==")
for produto in lista_produtos:
    print(produto)

print("==Lista de produtos ordenada pelo nome==")
lista_produtos_ordenada = sorted(lista_produtos, key=Produto.get_nome)
for produto in lista_produtos_ordenada:
    print(produto)

print("==Lista de produtos ordenada pelo preco==")
lista_produtos_ordenada = sorted(lista_produtos, key=Produto.get_preco)
for produto in lista_produtos_ordenada:
    print(produto)

Após esta primeira versão, realizei alterações para que os atributos sejam protegidos - seguindo as boas práticas de encapsulamento - e, desta forma, criei os métodos anotados com @property para que os valores dos atributos sejam obtidos. Mediante esse ajuste, alterei também o valor do parâmetro key de Produto.get_nome para Produto.nome e de Produto.get_preco para Produto.preco. Abaixo, segue a nova versão:

class Produto:

    def __init__(self, nome, preco):
        self._nome = nome
        self._preco = preco

    @property
    def nome(self):
        return self._nome

    @property
    def preco(self):
        return self._preco

    def __str__(self):
        return ("Nome: {} | Preco: R$ {:.2f}".format(self._nome, self._preco))

    def __iter__(self):
        pass


produto_01 = Produto("Arroz", 20.90)
produto_02 = Produto("Feijao", 10.90)
produto_03 = Produto("Alface", 5.10)
produto_04 = Produto("Tomate", 4.90)
produto_05 = Produto("Cebola", 1.00)

lista_produtos = [produto_01, produto_02, produto_03, produto_04, produto_05]

print("==Lista de produtos sem ordenacao==")
for produto in lista_produtos:
    print(produto)

print("==Lista de produtos ordenada pelo nome==")
lista_produtos_ordenada = sorted(lista_produtos, key=Produto.nome)
for produto in lista_produtos_ordenada:
    print(produto)

print("==Lista de produtos ordenada pelo preco==")
lista_produtos_ordenada = sorted(lista_produtos, key=Produto.preco)
for produto in lista_produtos_ordenada:
    print(produto)

Entretanto, ao executar esta nova versão, ocorre o erro do print: ![](Erro property object is not callable )

Desta forma, como posso ajustar o código para que eu possa seguir utilizando, como critério de ordenação, um dos atributos da classe através do método assinado com @property?

Grato desde já!

1 resposta
solução!

Ao invés de usar o Produto.atributo de chave, pode usar uma função anônima lambda. O código fica assim:

print("==Lista de produtos ordenada pelo nome==")
lista_produtos_ordenada = sorted(lista_produtos, key=lambda p: p.nome)
for produto in lista_produtos_ordenada:
    print(produto)

print("==Lista de produtos ordenada pelo preco==")
lista_produtos_ordenada = sorted(lista_produtos, key=lambda p: p.preco)
for produto in lista_produtos_ordenada:
    print(produto)

Mais informações sobre funções lambda: https://wiki.python.org.br/PythonFuncional#A_Express.2BAOM-o_Lambda https://docs.python.org/pt-br/3/reference/expressions.html#lambda

Espero ter ajudado.