1
resposta

[Sugestão] Aplicaçando as sugestões das Classes

main.py

import contatos_utils

caminho_csv = '/home/echo/curso-python/arquivos/dados/contatos.csv'
caminho_pickle = '/home/echo/curso-python/arquivos/dados/contatos.p'
caminho_json = '/home/echo/curso-python/arquivos/dados/contatos.json'
encoding = 'latin_1'

def main():
    while True:
        print("Menu:")
        print("1. Ler contatos do CSV")
        print("2. Gravar contatos em formato Pickle")
        print("3. Ler contatos em formato Pickle")
        print("4. Gravar contatos em formato JSON")
        print("5. Ler contatos em formato JSON")
        print("6. Sair")

        escolha = input("Escolha uma opção: ")

        if escolha == '1':
            # Ler contatos do CSV
            contatos_origem = contatos_utils.ContatoDAO.csv_contatos(caminho_csv, encoding)
            print_contatos(contatos_origem, "Contatos lidos do CSV:")

        elif escolha == '2':
            # Gravar contatos em formato Pickle
            contatos = contatos_utils.ContatoDAOpickle.save(contatos_origem, caminho_pickle)
            print("Contatos gravados em formato Pickle.")
        elif escolha == '3':
            # Ler contatos em formato Pickle
            contatos = contatos_utils.ContatoDAOpickle.seek(caminho_pickle)
            print_contatos(contatos, "Contatos lidos em formato Pickle:")
        elif escolha == '4':
            # Gravar contatos em formato JSON
            contatos_utils.ContatoDAOJSON.save(contatos_origem, caminho_json)
            print("Contatos gravados em formato JSON.")
        elif escolha == '5':
            # Ler contatos em formato JSON
            contatos = contatos_utils.ContatoDAOJSON.seek(caminho_json)
            print_contatos(contatos, "Contatos lidos em formato JSON:")
        elif escolha == '6':
            # Sair
            print("Saindo...")
            break
        else:
            # Opção inválida
            print("Opção inválida. Escolha novamente.")

def print_contatos(contatos, mensagem):
    print(mensagem)
    for contato in contatos:
        print(f'{contato.id} - {contato.nome} - {contato.email}')

if __name__ == "__main__":
    main()

e contatos_utils.py

from abc import ABC, abstractmethod
import csv
import pickle
import json
from contato import Contato

class ContatoDAO(ABC):

    @abstractmethod
    def seek(self, path):
        pass

    @abstractmethod
    def save(self, contacts, path):
        pass

    # cria uma lista para importar os dados do csv
    def csv_contatos(caminho: str, encoding: str='latin_1') -> list:
        contatos = []
        
        with open(caminho,encoding=encoding) as arquivo:
            # método de leitura do csv
            leitor = csv.reader(arquivo)
            
            # List Comprehension
            contatos = [Contato(id, nome, email) for id, nome, email in leitor]

            '''
            for linha in leitor:
                # percorre o csv
                id = linha[0]
                nome = linha[1]
                email = linha[2]

                # cria um obj e passa os atributos
                contato = Contato(id,nome,email)
                contatos.append(contato)
            '''
        return contatos


class ContatoDAOpickle(ContatoDAO):

    # Converte e salva a lista para pickes(obj serializado)
    @abstractmethod
    def save(contatos: Contato, caminho: str):
        with open(caminho, mode='wb') as arquivo:
            pickle.dump(contatos, arquivo)

    # Converte pickes para lista
    @abstractmethod
    def seek(caminho:str, encoding: str='latin_1') -> list:
        with open(caminho, mode='rb') as arquivo:
            contatos = pickle.load(arquivo,encoding=encoding)

        return contatos


class ContatoDAOJSON(ContatoDAO):

    # Converte e salva a lista para JSON
    @abstractmethod
    def save(contatos: Contato, caminho: str):
        with open(caminho, mode='w') as arquivo:
            # código omitido - Função Lambda - Função anônima (lambada input: output)
            json.dump(contatos, arquivo, default=lambda contato: contato.__dict__)
            
            #json.dump(contatos, arquivo, default=_contatos_json)
    
    # Sugestão anterior ao lambda
    def _contatos_json(contato):
        return contato.__dict__

    # Converte json para lista
    @abstractmethod
    def seek(caminho:str) -> list:
        contatos = []

        with open(caminho) as arquivo:
            contatos_json = json.load(arquivo)

            # List Comprehension
            contatos = [Contato(**contato) for contato in contatos_json]
            
            '''
            for contato in contatos_json:
                c = Contato(**contato)
                contatos.append(c)
            '''
        return contatos
1 resposta

Oii, Edgar! Tudo bem?

Mandou bem colocando em prática o conteúdo absorvido nas aulas! Certamente sua sugestão ajudará outros colegas que estão estudando o mesmo conteúdo.

Continue se empenhando nos estudos e qualquer dúvida, não hesite em recorrer ao fórum.

Bons estudos, Edgar!