2.19. Escrevendo módulos¶
Qualquer arquivo .py é um módulo. Dividir um script que está crescendo em alguns arquivos mantém cada arquivo curto e permite que auxiliares comuns sejam compartilhados entre scripts.
2.19.1. Dividindo um script¶
Tire um grupo relacionado de funções para seu próprio arquivo:
camera_utils.py
def banner():
print("OpenMV")
def label(text):
return "[" + text + "]"
main.py
import camera_utils
camera_utils.banner()
print(camera_utils.label("ready"))
Saída:
OpenMV
[ready]
Os dois arquivos ficam lado a lado no mesmo diretório. Quando main.py roda, import camera_utils lê camera_utils.py uma vez, executa suas instruções de nível superior e vincula o objeto de módulo resultante ao nome camera_utils em main. Um segundo import camera_utils de qualquer outro lugar retorna o mesmo objeto – os módulos ficam em cache após seu primeiro carregamento.
O nome de um módulo vem de seu nome de arquivo, então camera_utils.py é importado como import camera_utils.
2.19.2. Módulos de múltiplos arquivos (pacotes)¶
Um módulo também pode ser um diretório de arquivos em vez de um único .py. O nome do diretório torna-se o nome do módulo, e os arquivos dentro dele são seus submódulos:
camera_utils/
__init__.py
text.py
timing.py
__init__.py é o arquivo que roda quando o próprio pacote é importado; ele pode estar vazio ou pode reexportar nomes selecionados dos submódulos. Os submódulos são acessados com um nome pontuado:
import camera_utils.text
from camera_utils.timing import elapsed
camera_utils.text.label("ready")
Dentro do pacote, os submódulos podem acessar uns aos outros tanto pelo nome pontuado completo quanto por um import relativo que usa um ponto inicial para significar “este pacote”:
camera_utils/timing.py
from . import text # the sibling submodule
def stamp(value):
return text.label(str(value))
Para trazer um nome específico em vez disso, nomeie-o após o irmão pontuado:
from .text import label
def stamp(value):
return label(str(value))
Os imports relativos mantêm um pacote autocontido: renomear o diretório do pacote não exige editar todos os submódulos.
Use um pacote quando um único arquivo crescer além de um tamanho confortável, ou quando um conjunto de módulos relacionados pertence junto sob um mesmo namespace. Para scripts do dia a dia, um único arquivo .py é suficiente.
2.19.3. A proteção __name__¶
Todo módulo tem um nome embutido __name__. Seu valor depende de como o arquivo está sendo usado:
Quando o arquivo é executado diretamente,
__name__é definido como a string"__main__".Quando o arquivo é importado por outro script,
__name__é definido como o nome do módulo – o nome do arquivo sem.py.
O idioma que usa isso é:
label_util.py
def label(text):
return "[" + text + "]"
if __name__ == "__main__":
print(label("self-test"))
Saída (quando executado diretamente):
[self-test]
Quando o mesmo arquivo é importado em vez disso, __name__ é definido como o nome do módulo, então o bloco if é ignorado e nada extra é executado:
>>> import label_util
>>> label_util.__name__
'label_util'
Use o padrão para anexar um teste rápido de fumaça ou uma demonstração a um arquivo de biblioteca sem perturbar scripts que o importam.