Introdução
Neste laboratório, você aprenderá os fundamentos de organização e reutilização de código em Python trabalhando com módulos e pacotes (packages). Começaremos entendendo o que é um módulo Python e como seu comportamento de execução muda dependendo se ele é executado diretamente ou importado.
Em seguida, você praticará as duas principais maneiras de trazer código de módulos para o seu programa: a instrução import para carregar um módulo inteiro e a instrução from...import para carregar funções ou variáveis específicas. Finalmente, você aprenderá a estruturar módulos relacionados em um pacote para criar um projeto bem organizado e escalável. Todo o código será desenvolvido dentro do WebIDE, utilizando arquivos Python e o terminal.
Compreendendo Módulos Python
Um módulo em Python é simplesmente um arquivo contendo código Python, que possui a extensão .py. Módulos permitem que você organize seu código logicamente, tornando-o mais fácil de gerenciar e reutilizar. Funções, classes e variáveis definidas em um módulo podem ser usadas em outros scripts.
No seu WebIDE, você verá um explorador de arquivos no lado esquerdo. O ambiente do laboratório já criou um arquivo chamado hello.py no diretório ~/project.
Primeiro, abra hello.py para examinar seu conteúdo. Ele deve conter o seguinte código:
print("This code runs on import or direct execution.")
if __name__ == "__main__":
print("This code runs ONLY when the script is executed directly.")
O bloco if __name__ == "__main__": é uma construção especial em Python. A variável __name__ é uma variável embutida que é avaliada como o nome do módulo atual. Quando um script Python é executado diretamente a partir da linha de comando, seu __name__ é definido como a string "__main__". Esta instrução if permite que você escreva código que será executado apenas quando o arquivo for executado como o programa principal, e não quando for importado por outro módulo.
Vamos ver isso em ação. Abra o terminal no seu WebIDE e execute o script hello.py diretamente:
python3 hello.py
Você verá a seguinte saída, pois ambas as instruções print são executadas:
This code runs on import or direct execution.
This code runs ONLY when the script is executed directly.
Isso demonstra o comportamento de um script quando ele é o programa principal em execução. No próximo passo, veremos o que acontece quando o importamos como um módulo.
Importando Módulos com a Instrução import
A maneira mais comum de usar um módulo é importá-lo usando a instrução import. Isso torna todo o código do módulo disponível para o seu script atual.
No explorador de arquivos, você encontrará um arquivo vazio chamado main.py. Este será nosso script principal para o restante do laboratório.
Abra main.py e adicione a seguinte linha para importar o módulo hello:
import hello
print("The main.py script has finished.")
Salve o arquivo. Agora, execute main.py a partir do terminal:
python3 main.py
Observe a saída com atenção:
This code runs on import or direct execution.
The main.py script has finished.
Note que apenas a primeira instrução print de hello.py foi executada. O código dentro do bloco if __name__ == "__main__": foi ignorado. Isso ocorre porque, quando main.py importa hello, a variável __name__ no contexto de hello.py é definida como "hello" (o nome do módulo), e não como "__main__". Este recurso é essencial para criar módulos reutilizáveis que não geram efeitos colaterais indesejados ao serem importados.
Agora, vamos trabalhar com um módulo que contém mais do que apenas instruções de impressão. Abra o arquivo module_a.py. Ele contém uma variável, uma função e uma classe.
PI = 3.14159
def greet(name):
print(f"Hello, {name} from module_a!")
class Calculator:
def add(self, x, y):
return x + y
Modifique main.py para importar module_a e usar seus membros. Para acessar um membro de um módulo importado, você usa a sintaxe nome_do_modulo.nome_do_membro.
Substitua o conteúdo de main.py pelo seguinte:
import module_a
## Access the PI variable
print(f"The value of PI is {module_a.PI}")
## Call the greet function
module_a.greet("LabEx")
## Create an instance of the Calculator class and use its method
calc = module_a.Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")
Salve o arquivo e execute-o:
python3 main.py
A saída será:
The value of PI is 3.14159
Hello, LabEx from module_a!
5 + 3 = 8
Isso demonstra como a instrução import carrega um módulo inteiro, e você acessa seu conteúdo usando o nome do módulo como prefixo.
Importando Objetos Específicos com from...import
Às vezes, você precisa apenas de alguns itens específicos de um módulo. A instrução from...import permite que você importe funções, classes ou variáveis específicas diretamente para o namespace (espaço de nomes) do seu script atual. Isso significa que você pode usá-las sem o prefixo nome_do_modulo..
Vamos modificar main.py para usar este método de importação. Em vez de importar o module_a inteiro, importaremos apenas a variável PI e a função greet.
Atualize main.py com o seguinte código:
from module_a import PI, greet
## Access PI and greet directly without the module prefix
print(f"The value of PI is {PI}")
greet("World")
Salve o arquivo e execute-o a partir do terminal:
python3 main.py
A saída será:
The value of PI is 3.14159
Hello, World from module_a!
Como você pode ver, PI e greet são usadas diretamente. No entanto, se você tentar acessar algo que não importou, como a classe Calculator, você receberá um erro.
Tente agora. Adicione as seguintes linhas ao final de main.py:
calc = Calculator()
print(calc.add(10, 20))
Execute o script novamente:
python3 main.py
Desta vez, o script falhará com um NameError:
The value of PI is 3.14159
Hello, World from module_a!
Traceback (most recent call last):
File "/home/labex/project/main.py", line 7, in <module>
calc = Calculator()
NameError: name 'Calculator' is not defined
Este erro confirma que apenas os objetos especificados na instrução from...import são trazidos para o namespace atual. Este método pode tornar seu código mais legível, mas também aumenta o risco de conflitos de nomes se você importar objetos com o mesmo nome de módulos diferentes.
Antes de prosseguir para o próximo passo, remova as duas linhas que causaram o erro de main.py.
Compreendendo e Utilizando Pacotes Python
À medida que os projetos crescem, você pode querer organizar módulos relacionados em uma única hierarquia de diretórios. É para isso que servem os pacotes (packages). Um pacote é um diretório que contém um arquivo especial chamado __init__.py (que pode estar vazio). A presença deste arquivo informa ao Python para tratar o diretório como um pacote.
Vamos criar um pacote para conter nosso module_a.
Primeiro, crie um novo diretório chamado my_package no diretório ~/project. Você pode fazer isso clicando com o botão direito no explorador de arquivos e selecionando "Nova Pasta".
mkdir my_package
Em seguida, crie o arquivo __init__.py necessário dentro do novo diretório my_package.
touch my_package/__init__.py
Agora, mova module_a.py para o diretório my_package. Você pode arrastar e soltar o arquivo no explorador de arquivos.
mv module_a.py my_package/
A estrutura do seu projeto agora deve ser assim:
~/project/
├── main.py
├── hello.py
└── my_package/
├── __init__.py
└── module_a.py
Com esta estrutura de pacote estabelecida, precisamos atualizar como importamos module_a no nosso script main.py. Para importar um módulo de um pacote, você usa nomes de módulos pontilhados, como nome_do_pacote.nome_do_modulo.
Abra main.py e modifique-o para importar a função greet de my_package.module_a:
from my_package.module_a import greet
greet("Package")
Salve o arquivo e execute-o:
python3 main.py
Você deverá ver a seguinte saída:
Hello, Package from module_a!
Isso mostra como importar um objeto específico de um módulo dentro de um pacote. Alternativamente, você poderia importar o módulo em si:
## Alternative import style
import my_package.module_a
my_package.module_a.greet("Alternative")
Pacotes são uma ferramenta poderosa para organizar bases de código grandes, como bibliotecas e frameworks, em uma estrutura clara e de fácil manutenção.
Resumo
Neste laboratório, você aprendeu os conceitos essenciais de organização de código em Python. Você começou entendendo o que é um módulo e a finalidade do bloco if __name__ == "__main__": para criar código reutilizável. Em seguida, praticou a importação de módulos usando a sintaxe import nome_do_modulo e o acesso aos seus membros com notação de ponto.
Além disso, você explorou a instrução from...import para trazer objetos específicos de um módulo diretamente para o namespace do seu script. Finalmente, você aprendeu como estruturar módulos relacionados em um pacote, criando um diretório com um arquivo __init__.py, e como importar desse pacote. Essas habilidades são fundamentais para escrever aplicações Python limpas, organizadas e escaláveis.



