+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Módulos customizados

+ +
+ +
+
+ + + + +
+ +
+

Módulos customizados#

+

Nós já aprendemos sobre funções e módulos nativos. Agora é hora de elevar o nível e aprender a criar nossos próprios módulos. Vamos começar com um exemplo de projeto pra explicar e contextualizar sobre módulos customizados.

+
+

Nota (múltiplos arquivos .py)

+

Neste capítulo, vamos trabalhar com múltiplos arquivos .py. Para fins didáticos, no início de cada código eu vou colocar o nome do arquivo no qual o código está sendo escrito. Por exemplo, se o código está sendo escrito no arquivo estoque.py, eu vou colocar o seguinte comentário no início do código: # estoque.py. Ou então se o arquivo está dentro de uma pasta chamada funcoes, por exemplo, eu vou informar o caminho relativo do arquivo da seguinte forma: # funcoes/estoque.py. Preste atenção nesses comentários para saber em qual arquivo o código está sendo escrito.

+

Isso é apenas para fins didáticos, pois no mundo real, você não precisa colocar tais comentários.

+
+
+

O projeto#

+

Vamos começar com um exemplo de projeto de um sistema de gerenciamento de vendas online simulando um e-commerce.

+
+
+
# sistema_bancario.py
+
+usuarios = {}
+
+
+def registrar_usuario(nome: str) -> None:
+    usuarios[nome] = {"saldo": 0, "transacoes": []}
+    print(f"Usuário {nome} registrado com sucesso!")
+
+
+def verificar_saldo(nome: str) -> int:
+    return usuarios[nome]["saldo"]
+
+
+def depositar(nome: str, quantia: int) -> None:
+    usuarios[nome]["saldo"] += quantia
+    usuarios[nome]["transacoes"].append(f"Depositou {quantia}")
+    print(f"Depositou {quantia} na conta de {nome}.")
+
+
+def sacar(nome: str, quantia: int) -> None:
+    if quantia > usuarios[nome]["saldo"]:
+        print("Saldo insuficiente!")
+    else:
+        usuarios[nome]["saldo"] -= quantia
+        usuarios[nome]["transacoes"].append(f"Sacou {quantia}")
+        print(f"Sacou {quantia} da conta de {nome}.")
+
+
+# Histórico de Transações
+def mostrar_transacoes(nome: str) -> list:
+    return usuarios[nome]["transacoes"]
+
+
+# Descomente a linha abaixo para capturar do terminal um nome
+# nome = input("Digite seu nome para registrar: ")
+nome = "Henrique"
+registrar_usuario(nome)
+
+while True:
+    print("1. Verificar Saldo")
+    print("2. Depositar")
+    print("3. Sacar")
+    print("4. Mostrar Transações")
+    print("5. Sair")
+
+    # Descomente a linha abaixo para capturar do terminal uma opção
+    # opcao = int(input("Escolha uma opção: "))
+    opcao = 1
+
+    if opcao == 1:
+        print(f"Seu saldo é: {verificar_saldo(nome)}")
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 2:
+        quantia = float(input("Digite a quantia para depositar: "))
+        depositar(nome, quantia)
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 3:
+        quantia = float(input("Digite a quantia para sacar: "))
+        sacar(nome, quantia)
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 4:
+        print(f"Transações: {mostrar_transacoes(nome)}")
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 5:
+        print("Até mais!")
+        # Este break é o de saída do loop! Não remova!
+        break
+    else:
+        print("Opção inválida. Tente novamente.")
+
+
+
+
+
Usuário Henrique registrado com sucesso!
+1. Verificar Saldo
+2. Depositar
+3. Sacar
+4. Mostrar Transações
+5. Sair
+Seu saldo é: 0
+
+
+
+
+

Tome o tempo que for necessário e leia o código acima. Nesta altura do livro, não há nada acima que não tenha sido ensinado aqui no livro. Não continue a leitura até que você tenha entendido a ideia do projeto. Não se preocupe em entender cada detalhe do código, o importante é ter uma visão geral do que está sendo feito. Se você não entendeu algo, volte e revise os capítulos anteriores referentes ao tema que você não entendeu.

+
+
+
+

Separando o projeto em módulos#

+

Conforme vimos no final do código, ele funciona, mas o projeto está um pouco longo (mais que 70 linhas) e acaba ficando um pouco confuso e difícil de manter. Vamos dividir o código em módulos customizados para facilitar a manutenção e organização do código.

+

Se observarmos o nosso projeto, ele contém alguns grandes blocos:

+
    +
  • Controlar e registrar usuários do sistema bancário

  • +
  • Realizar operações na conta bancária (saque, depósito, ver saldo)

  • +
  • Ver o histórico de transações

  • +
  • Fluxo principal do sistema (escolha e execução das operações)

  • +
+

Dada essa divisão, vamos criar um módulo para cada um desses blocos. Cada módulo vai ser um arquivo .py separado. Vou criar os sequintes arquivos (a princípio em branco):

+
    +
  • gerenciamento_usuarios.py

  • +
  • gerenciamento_contas.py

  • +
  • historico_transacoes.py

  • +
  • sistema.py

  • +
+

Cada um deles vai conter um dos blocos acima. Vamos começar com o arquivo gerenciamento_usuarios.py:

+
# gerenciamento_usuarios.py
+usuarios = {}
+
+
+def registrar_usuario(nome):
+    usuarios[nome] = {"saldo": 0, "transacoes": []}
+    print(f"Usuário {nome} registrado com sucesso!")
+
+
+

Até aqui nenhuma novidade. O que vem a seguir representa a importação dos dados em outro módulo.

+
# gerenciamento_contas.py
+from gerenciamento_usuarios import usuarios
+
+
+def verificar_saldo(nome):
+    return usuarios[nome]["saldo"]
+
+
+def depositar(nome, quantia):
+    usuarios[nome]["saldo"] += quantia
+    usuarios[nome]["transacoes"].append(f"Depositou {quantia}")
+    print(f"Depositou {quantia} na conta de {nome}.")
+
+
+def sacar(nome, quantia):
+    if quantia > usuarios[nome]["saldo"]:
+        print("Saldo insuficiente!")
+    else:
+        usuarios[nome]["saldo"] -= quantia
+        usuarios[nome]["transacoes"].append(f"Sacou {quantia}")
+        print(f"Sacou {quantia} da conta de {nome}.")
+
+
+

Em gerenciamento_contas.py, logo na primeira linha, estamos importando do módulo gerenciamento_usuarios a variável usuarios.

+

Vamos seguir com a divisão.

+
# historico_transacoes.py
+from gerenciamento_usuarios import usuarios
+
+
+def mostrar_transacoes(nome):
+    return usuarios[nome]["transacoes"]
+
+
+

E, finalmente, o arquivo sistema.py:

+
# sistema.py
+from gerenciamento_contas import depositar, sacar, verificar_saldo
+from gerenciamento_usuarios import registrar_usuario
+from historico_transacoes import mostrar_transacoes
+
+nome = "Henrique"
+registrar_usuario(nome)
+
+while True:
+    print("1. Verificar Saldo")
+    print("2. Depositar")
+    print("3. Sacar")
+    print("4. Mostrar Transações")
+    print("5. Sair")
+
+    # Descomente a linha abaixo para capturar do terminal uma opção
+    # opcao = int(input("Escolha uma opção: "))
+    opcao = 1
+
+    if opcao == 1:
+        print(f"Seu saldo é: {verificar_saldo(nome)}")
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 2:
+        quantia = float(input("Digite a quantia para depositar: "))
+        depositar(nome, quantia)
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 3:
+        quantia = float(input("Digite a quantia para sacar: "))
+        sacar(nome, quantia)
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 4:
+        print(f"Transações: {mostrar_transacoes(nome)}")
+        # Remova a instrução break para o loop funcionar
+        break
+    elif opcao == 5:
+        print("Até mais!")
+        # Este break é o de saída do loop! Não remova!
+        break
+    else:
+        print("Opção inválida. Tente novamente.")
+
+
+

Quem permite reutilizar funções, variáveis e outras coisas de módulos são as linhas de importações, como em sistema.py:

+
# sistema.py
+from gerenciamento_contas import depositar, sacar, verificar_saldo
+from gerenciamento_usuarios import registrar_usuario
+from historico_transacoes import mostrar_transacoes
+...
+
+
+

Essas linhas importam as funções depositar, sacar, verificar_saldo, registrar_usuario e mostrar_transacoes dos respectivos módulos. Cada módulo representa um arquivo .py.

+

Se você executar o script sistema.py, o projeto vai funcionar da mesma forma que antes, mas agora está organizado em módulos customizados. Cada módulo é responsável por uma parte do projeto.

+

No final a organização do nosso projeto ficou conforme a imagem abaixo:

+../_images/09-03-modulos.png +
+

Visão geral#

+

Poderíamos avançar no tema e aprofundar ainda mais, mas não vamos. A ideia principal é que você compreenda o conceito básico da divisão em módulos, cada um com sua própria responsabilidade.

+

É possível dividir de várias formas, e não existe uma regra sobre como fazer tal divisão. Normalmente a divisão é baseada em responsabilidades e funcionalidades. Cada módulo deve ser responsável por uma parte ou escopo específico. E quem define isso é você, meu caro leitor! Aqui assumo que é necessário um pouco de criatividade para enxergar tais divisões, sim. Eu nunca disse que quem programa não precisa ser criativo… 😉

+

É possível organizar ainda o projeto não só em módulos (arquivos .py separados) mas também em pastas e subpastas. Mas, por enquanto, vamos ficar com o mais simples.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+
+ + +
+ + +