2.19. Psaní modulů

Jakýkoli soubor .py je modul. Rozdělení rostoucího skriptu do několika souborů udržuje každý soubor krátký a umožňuje sdílet společné pomocné funkce mezi skripty.

2.19.1. Rozdělení skriptu

Vytáhněte související skupinu funkcí do vlastního souboru:

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"))

Výstup:

OpenMV
[ready]

Oba soubory leží vedle sebe ve stejném adresáři. Když main.py běží, import camera_utils přečte camera_utils.py jednou, vykoná jeho příkazy nejvyšší úrovně a naváže výsledný objekt modulu na jméno camera_utils v main. Druhý import camera_utils odkudkoli jinud vrátí tentýž objekt – moduly se po prvním načtení ukládají do mezipaměti.

Jméno modulu pochází z jeho názvu souboru, takže camera_utils.py se importuje jako import camera_utils.

2.19.2. Vícesouborové moduly (balíčky)

Modul může být také adresářem souborů namísto jediného .py. Jméno adresáře se stane jménem modulu a soubory uvnitř jsou jeho podmoduly:

camera_utils/
    __init__.py
    text.py
    timing.py

__init__.py je soubor, který se spustí, když je importován samotný balíček; může být prázdný, nebo může znovu exportovat vybraná jména z podmodulů. K podmodulům se sahá pomocí tečkového jména:

import camera_utils.text
from camera_utils.timing import elapsed

camera_utils.text.label("ready")

Uvnitř balíčku se podmoduly mohou navzájem dosáhnout buď úplným tečkovým jménem, nebo relativním importem, který používá úvodní tečku ve významu „tento balíček“:

camera_utils/timing.py

from . import text             # the sibling submodule

def stamp(value):
    return text.label(str(value))

Chcete-li místo toho vtáhnout konkrétní jméno, pojmenujte jej za tečkovým sourozencem:

from .text import label

def stamp(value):
    return label(str(value))

Relativní importy udržují balíček soběstačný: přejmenování adresáře balíčku nevyžaduje úpravu každého podmodulu.

Balíček použijte, když jediný soubor přeroste pohodlnou velikost, nebo když sada souvisejících modulů patří k sobě pod jedním jmenným prostorem. Pro každodenní skripty stačí jediný soubor .py.

2.19.3. Stráž __name__

Každý modul má vestavěné jméno __name__. Jeho hodnota závisí na tom, jak se soubor používá:

  • Když je soubor spuštěn přímo, __name__ je nastaveno na řetězec "__main__".

  • Když je soubor importován jiným skriptem, __name__ je nastaveno na jméno modulu – název souboru bez .py.

Idiom, který toho využívá, je:

label_util.py

def label(text):
    return "[" + text + "]"

if __name__ == "__main__":
    print(label("self-test"))

Výstup (při přímém spuštění):

[self-test]

Když je tentýž soubor místo toho importován, __name__ je nastaveno na jméno modulu, takže se blok if přeskočí a nic navíc se nespustí:

>>> import label_util
>>> label_util.__name__
'label_util'

Tento vzor použijte k připojení rychlého ověřovacího testu nebo ukázky k souboru knihovny, aniž byste narušili skripty, které jej importují.