2.19. Skriva moduler¶
Vilken .py-fil som helst är en modul. Att dela upp ett växande skript över några filer håller varje fil kort och låter gemensamma hjälpfunktioner delas mellan skript.
2.19.1. Dela upp ett skript¶
Lyft ut en sammanhörande grupp funktioner till en egen fil:
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"))
Utdata:
OpenMV
[ready]
De två filerna ligger sida vid sida i samma katalog. När main.py körs läser import camera_utils filen camera_utils.py en gång, exekverar dess satser på toppnivå och binder det resulterande modulobjektet till namnet camera_utils i main. En andra import camera_utils från någon annanstans returnerar samma objekt – moduler cachas efter sin första laddning.
En moduls namn kommer från dess filnamn, så camera_utils.py importeras som import camera_utils.
2.19.2. Moduler med flera filer (paket)¶
En modul kan också vara en katalog med filer snarare än en enda .py. Katalogens namn blir modulnamnet, och filerna inuti är dess undermoduler:
camera_utils/
__init__.py
text.py
timing.py
__init__.py är filen som körs när själva paketet importeras; den kan vara tom, eller den kan återexportera utvalda namn från undermodulerna. Undermodulerna nås med ett punktnotationsnamn:
import camera_utils.text
from camera_utils.timing import elapsed
camera_utils.text.label("ready")
Inuti paketet kan undermoduler nå varandra antingen med det fullständiga punktnotationsnamnet eller med en relativ import som använder en inledande punkt för att betyda ”detta paket”:
camera_utils/timing.py
from . import text # the sibling submodule
def stamp(value):
return text.label(str(value))
För att istället dra in ett specifikt namn, namnge det efter den punktnoterade syskonmodulen:
from .text import label
def stamp(value):
return label(str(value))
Relativa importer håller ett paket självständigt: att byta namn på paketkatalogen kräver inte att varje undermodul redigeras.
Använd ett paket när en enda fil växer förbi en bekväm storlek, eller när en uppsättning relaterade moduler hör samman under en namnrymd. För vardagsskript räcker en enda .py-fil.
2.19.3. __name__-skyddet¶
Varje modul har ett inbyggt namn __name__. Dess värde beror på hur filen används:
När filen körs direkt sätts
__name__till strängen"__main__".När filen importeras av ett annat skript sätts
__name__till modulnamnet – filnamnet utan.py.
Idiomet som använder detta är:
label_util.py
def label(text):
return "[" + text + "]"
if __name__ == "__main__":
print(label("self-test"))
Utdata (vid direkt körning):
[self-test]
När samma fil istället importeras sätts __name__ till modulnamnet, så if-blocket hoppas över och inget extra körs:
>>> import label_util
>>> label_util.__name__
'label_util'
Använd mönstret för att fästa ett snabbt funktionstest eller en demo på en biblioteksfil utan att störa skript som importerar den.