2.19. Moduulien kirjoittaminen¶
Mikä tahansa .py-tiedosto on moduuli. Kasvavan skriptin jakaminen muutaman tiedoston kesken pitää jokaisen tiedoston lyhyenä ja antaa jakaa yhteisiä apufunktioita skriptien välillä.
2.19.1. Skriptin jakaminen¶
Vedä toisiinsa liittyvä funktioryhmä omaan tiedostoonsa:
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"))
Tuloste:
OpenMV
[ready]
Kaksi tiedostoa sijaitsevat vierekkäin samassa hakemistossa. Kun main.py suoritetaan, import camera_utils lukee tiedoston camera_utils.py kerran, suorittaa sen ylätason lauseet ja sitoo tuloksena olevan moduuliolion nimeen camera_utils tiedostossa main. Toinen import camera_utils mistä tahansa muualta palauttaa saman olion – moduulit välimuistitetaan ensimmäisen latauksensa jälkeen.
Moduulin nimi tulee sen tiedostonimestä, joten camera_utils.py tuodaan muodossa import camera_utils.
2.19.2. Monitiedostoiset moduulit (paketit)¶
Moduuli voi olla myös tiedostojen hakemisto yksittäisen .py-tiedoston sijaan. Hakemiston nimestä tulee moduulin nimi, ja sen sisällä olevat tiedostot ovat sen alimoduuleja:
camera_utils/
__init__.py
text.py
timing.py
__init__.py on tiedosto, joka suoritetaan, kun paketti itse tuodaan; se voi olla tyhjä, tai se voi viedä uudelleen valittuja nimiä alimoduuleista. Alimoduulit tavoitetaan pisteellä erotetulla nimellä:
import camera_utils.text
from camera_utils.timing import elapsed
camera_utils.text.label("ready")
Paketin sisällä alimoduulit voivat tavoittaa toisensa joko täydellä pisteellä erotetulla nimellä tai suhteellisella tuonnilla, joka käyttää alkupistettä tarkoittamaan ”tämä paketti”:
camera_utils/timing.py
from . import text # the sibling submodule
def stamp(value):
return text.label(str(value))
Vetääksesi sen sijaan tietyn nimen, nimeä se pisteellä erotetun sisaren mukaan:
from .text import label
def stamp(value):
return label(str(value))
Suhteelliset tuonnit pitävät paketin omavaraisena: pakettihakemiston uudelleennimeäminen ei vaadi jokaisen alimoduulin muokkaamista.
Käytä pakettia, kun yksittäinen tiedosto kasvaa mukavan koon yli tai kun joukko toisiinsa liittyviä moduuleja kuuluu yhteen yhden nimiavaruuden alle. Jokapäiväisiin skripteihin yksittäinen .py-tiedosto riittää.
2.19.3. __name__-suojaus¶
Jokaisella moduulilla on sisäänrakennettu nimi __name__. Sen arvo riippuu siitä, miten tiedostoa käytetään:
Kun tiedosto suoritetaan suoraan,
__name__asetetaan merkkijonoksi"__main__".Kun toinen skripti tuo tiedoston,
__name__asetetaan moduulin nimeksi – tiedostonimeksi ilman.py-päätettä.
Tätä käyttävä idiomi on:
label_util.py
def label(text):
return "[" + text + "]"
if __name__ == "__main__":
print(label("self-test"))
Tuloste (kun suoritetaan suoraan):
[self-test]
Kun sama tiedosto sen sijaan tuodaan, __name__ asetetaan moduulin nimeksi, joten if-lohko ohitetaan eikä mitään ylimääräistä suoriteta:
>>> import label_util
>>> label_util.__name__
'label_util'
Käytä mallia liittääksesi nopean savutestin tai demon kirjastotiedostoon häiritsemättä skriptejä, jotka tuovat sen.