2.19. Escrever módulos¶
Qualquer ficheiro .py é um módulo. Dividir um script crescente por vários ficheiros mantém cada ficheiro curto e permite que auxiliares comuns sejam partilhados entre scripts.
2.19.1. Dividir um script¶
Retire um grupo relacionado de funções para o seu próprio ficheiro:
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 ficheiros ficam lado a lado no mesmo diretório. Quando main.py é executado, import camera_utils lê camera_utils.py uma vez, executa as suas instruções de nível superior e associa o objeto módulo resultante ao nome camera_utils em main. Um segundo import camera_utils a partir de qualquer outro lugar devolve o mesmo objeto – os módulos são colocados em cache após a sua primeira carga.
O nome de um módulo vem do seu nome de ficheiro, por isso camera_utils.py é importado como import camera_utils.
2.19.2. Módulos com vários ficheiros (pacotes)¶
Um módulo pode também ser um diretório de ficheiros em vez de um único .py. O nome do diretório torna-se o nome do módulo, e os ficheiros dentro são os seus submódulos:
camera_utils/
__init__.py
text.py
timing.py
__init__.py é o ficheiro que é executado quando o pacote em si é importado; pode estar vazio, ou pode re-exportar nomes selecionados dos submódulos. Os submódulos são acessíveis com um nome com ponto:
import camera_utils.text
from camera_utils.timing import elapsed
camera_utils.text.label("ready")
Dentro do pacote, os submódulos podem aceder uns aos outros quer pelo nome completo com ponto, quer por uma importação relativa 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 importar um nome específico, nomeie-o depois do irmão com ponto:
from .text import label
def stamp(value):
return label(str(value))
As importações relativas mantêm um pacote autocontido: renomear o diretório do pacote não requer editar cada submódulo.
Use um pacote quando um único ficheiro cresce além de um tamanho confortável, ou quando um conjunto de módulos relacionados pertence a um único espaço de nomes. Para scripts do quotidiano, um único ficheiro .py é suficiente.
2.19.3. O guarda __name__¶
Todos os módulos têm um nome integrado __name__. O seu valor depende de como o ficheiro está a ser utilizado:
Quando o ficheiro é executado diretamente,
__name__é definido com a string"__main__".Quando o ficheiro é importado por outro script,
__name__é definido com o nome do módulo – o nome do ficheiro sem.py.
O idioma que utiliza isto é:
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 ficheiro é importado em vez de executado, __name__ é definido com o nome do módulo, pelo que o bloco if é ignorado e não é executado mais nada:
>>> import label_util
>>> label_util.__name__
'label_util'
Use o padrão para associar um teste rápido ou demonstração a um ficheiro de biblioteca sem perturbar os scripts que o importam.