Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Kuten aiemmin mainittiin, moduulit ovat koodia sisältäviä tiedostoja. Moduulin voi siis ajaa tiedostona, mutta moduuleja voi käyttää muullakin tavalla; moduulin voi ladata toiseen jolloin sen muuttujat, funktiot ja luokat saadaan käyttöön toisessakin moduulissa.

Tämä onnistuu avainsanalla import. Avainsanat ovat Pythonissa jonkun tietyn toiminnon - tässä tapauksessa moduulin lataamisen - suorittavia tunnisteita. Yksinkertaisimmillaan kirjoitetaan peräkkäin import ja ladattavan moduulin nimi. Modulin sisältämiä tunnisteita voi käyttää ns. piste operaattorilla; ladatun moduulin nimen jälkeen kirjoitetaan piste ja käytettävä tunniste.

Tässä esimerkissä ensimmäisessä moduulissa on säilötään merkkijono muuttujaan ja toinen moduuli lataa ensimmäisen ja tulostaa sen sisältämän merkkijonon. Moduulit kannattaa yksinkertaisuuden ja ongelmien välttämiseksi pitää samassa hakemistossa, vaikka moduuleita voi myös ladata eri hakemistoista. Ladattaessa moduulia, siitä tehdään (ohjelman suorituksen nopeuttamiseksi) .pyc tiedosto, joka sisältää moduulin tavukoodiksi purettuna, jota Python tulkki käyttää ohjelmien ajamiseen.

esim1a.py:

Code Block
 merkkijono = "Tama on ensimmäisen modulin merkkijono."

esim1b.py:

Code Block
import esim1a

print(esim1a.merkkijono)
input("Paina Enter nappainta lopettaaksesi")

Ladata voi myös hieman toisella tavalla avainsanaa from käyttämällä. Kirjoittamalla from moduulin nimi import voidaan listata asiat, pilkulla erotettuna, ladattavista tunnisteista - kirjoittamalla tähtimerkkin ladataan koko moduulin sisältö. Lataamalla tällä tavalla tunnisteita voi käyttää ilman moduulin nimeä ja pisteoperaattoria.

esim1c.py:

Code Block
from esim1a import merkkijono

print(merkkijono)
input("Paina Enter nappainta lopettaaksesi")

Huomion arvoinen seikka on sekin, ettei ladattava moduuli toimi pelkkänä tietovarastona vaan senkin koodi ajetaan import avainsanan yhteydessä. Sen takia, jos ladattavassa modulissa käytetään esim funktiota input, ohjelma pysähtyy modulin latauksen yhteydessä kysymään merkkijonoa.

esim1d.py:

Code Block
 merkkijono = input("Anna merkkijono ensimmäiselle modulille: ")

esim1e.py:

Code Block
import esim1d

print(esim1d.merkkijono)
input("Paina Enter nappainta lopettaaksesi")

Miksi sitten koodia pitäisi jaella eri moduuleihin? Tärkein syy on jo luodun koodin uudelleen käyttäminen; jos joku on jo tehnyt modulin, joka tekee jonkun monimutkaisen toiminnon, sitä ei tarvitse koodata uudestaan kun joku tarvii samoja toimintoja. Eihän kukaan tao omia työkaluja, vaan hankkii ne kaupasta; samoin moduulit toimivat ohjelmoinnissa työkaluina, jotka joku toinen on jo keksinyt ja ohjelmoinut.

Näissä pienissä esimerkeissä (varsinkaan tässä vaiheessa) ei välttämättä tule tämmöisen koodin kierrättämisen tarpeellisuus esiin. Useimmat esimerkit tulevat yhä olemaan yhteen moduuliin tehtyjä koodinpätkiä. Sen sijaan tullaan esittelemään joitain Pythoniin sisäänrakennettuja, ns. standardikirjastoon kuuluvia moduuleja.

Yksinkertainen esimerkki standardikirjastosta on unicodedata; se sisältää unicode merkistöstandardi liittyvää tietoa kuten funktiot merkin nimen ja numeron selvittämistä varten. Merkkikoodauksia käytetään, koska tietokoneet periaatteessa käsittelevät kaikkea tietoa kokonaislukuina ja näin tekstiä esitettäessä jokaiselle kirjaimelle täytyy määrittää jokin numero arvo. Unicode on yksi tämmöinen merkkien koodausjärjestelmä.

ASCII on yleisempi merkistö, mutta sisältää lähinnä latinalaiset aakkoset, mutta unicode järjestelmään on pyritty keräämään mahdollisimman monen kirjoitusjärjestelmän merkki. Tämmöinen tiedonkerääminen useista merkeistä olisi kova urakka, mutta demonstroi hyvin miksi jotkut asiat kannattaa säilöä moduuleihin. Tämä esimerkki tulostaa muutaman merkin unicodessa määritellyn nimen.

Code Block
from unicodedata import name

print(name("a"))

print(name("B"))

print(name("9"))

input("Paina Enter-nappainta lopettaaksesi")

Vielä yksi asia moduleihin liittyen on tietyt ennaltamääritellyt moduuli kohtaiset muuttujat. Nämä muuttujat sisältävät tietoa modulista kuten moduulin kuvauksen ja modulin sijainnin. Pythonissa on muitakin vastaavia muuttujia, joilla on ohjelmassa erikoismerkitys, ja ne tunnistaa siitä, että ne aina alkavat ja loppuvat kahdella alaviivalla. Tämän takia kahdella alaviivalla alkavia ja loppuvia tunnisteita ei kannata itse käyttää ellei tiedä mitä ne ovat, koska jotkut voivat olla ohjelman suorittamisen kannalta keskeisiä.

Seuraava ohjelma tulostaa unicodedata moduulista nimen _name, modulin sijainnin __file_ ja modulin kuvauksen _doc_. Rivinvaihdot on lisätty selkeyden vuoksi.

Code Block
import unicodedata

print("nimi:\n" + unicodedata.__name__)

print("\nsijainti:\n" + unicodedata.__file__)

print("\nkuvaus:\n" + unicodedata.__doc__)

input("\nPaina Enter-nappainta lopettaaksesi")

Myös päämodulissa - moduuli, jota suoritetaan - on samat erikoismuuttujat; niillä on samat nimet kuin unicodedata esimerkissä. Niiden käyttöön ei vain tarvitse kirjoittaa modulin nimeä. Omiin moduuleihin voi tehdä kuvauksen kirjoittamalla moduulin alkuun kolmella lainaus- tai heittomerkillä alkavan ja loppuvan merkkijonon; tämä arvo sijoitetaan automaattisesti moduulin muuttujaan _doc_.

Code Block
"""Tämä on omatekoisen modulin
yksinkertainen kuvaus."""

import unicodedata

print("nimi:\n" + __name__)

print("\nkuvaus:\n" + __doc__)

input("\nPaina Enter-nappäinta lopettaaksesi")

Kuten näkyy muuttujan _name_ arvo ei olekkaan moduulin varsinanen nimi vaan siinä lukee _main_, joka viittaa päämoduliin. Moduulille annetaan tämä nimi vain silloin kun se on päämoduuli. Näitä tietoja ei aina tarvita, mutta joskus niistäkin on hyötyä joten ne on hyvä tietää.