post

Python nb-no:Moduler

Contents

Introduksjon

Du har fått se hvordan du kan bruke kode om igjen i programmet ved å definere funksjoner, men hva hvis du hadde lyst til å bruke noen funksjoner om igjen i andre programmer som du skriver? Som du kanskje har gjettet er svaret moduler. En modul er en fil som inneholder alle funksjonene og variablene du har definert.

For å bruke modulen om igjen i andre programmer filen ha filutvidelsen .py.

Du kan importere en modul til et annet program for å ta i bruk funksjonaliteten dens. På samme måte kan vi bruke Pythons standardbibliotek. Først skal vi se på hvordan man kan bruke moduler fra standardbiblioteket.

Eksempel:

#!/usr/bin/python
# Filnavn: bruke_sys.py

import sys

print('Kommandolinjeargumentene er:')
for i in sys.argv:
    print(i)

print('nnPYTHONPATH-en er', sys.path, 'n')

Output:

   $ python bruke_sys.py vi er argumenter
   Kommandolinjeargumentene er:
   bruke_sys.py
   vi
   er
   argumenter


   PYTHONPATH-en er ['', 'C:\tmp', 'C:\Python30\python30.zip',
   'C:\Python30\DLLs', 'C:\Python30\lib', 'C:\Python30\lib\plat-win',
   'C:\Python30', 'C:\Python30\lib\site-packages']

Hvordan det virker:

Først importerer vi sys-modulen med import-påstanden. Dette betyr at vi gir beskjed til Python om at vi vil bruke denne modulen. sys-modulen inneholder funksjonalitet som har sammenheng med Python-tolkeren og omgivelsene dens, altså systemet ditt.

Når Python utfører import sys-påstanden ser den etter sys.py-modulen i mappene som er skrevet opp i sys.path-variabelen. Hvis det finner filen, kjører Python påstandene i hovedblokken til modulen, og så er modulen tilgjengelig for deg. Legg merke til at denne initialiseringen bare skjer første gangen vi importerer en modul.

Vi får tak i argv-variabelen i sys-modulen ved å bruke punktum, som i sys.argv. Det indikerer at navnet er del av sys-modulen, og en av fordelene med dette er at navnet ikke kommer i konflikt med navn du har i programmet ditt, for eksempel argv.

sys.argv-variabelen er en liste med strenger (lister forklares i et senere kapittel. For å si det på en annen måte, så inneholder sys.argv listen med kommandolinjearmugentene som du gir til programmet ditt gjennom kommandolinjen (se på “vi er argumenter” etter filnavnet).

Se etter en måte å spesifisere kommandolinjeargumenter til programmet i menyene dersom du bruker et IDE.

Når vi kjører python bruke_sys.py vi er argumenter, kjører vi modulen bruke_sys.py med python-kommandoen, og de andre tingene som følger er argumenter som sendes til programmet. Python lagrer kommandolinjeargumentene i sys.argv-variabelen slik at vi kan bruke dem.

Husk på at navnet på skriptet som kjører alltid er det første argumentet i sys.argv-listen. I dette tilfellet har vi 'bruke_sys.py' som sys.argv[0], 'vi' som sys.argv[1], 'er' som sys.argv[2] og 'argumenter' som sys.argv[3]. Legg merke til at Python starter med å telle fra 0, og ikke 1.

sys.path inneholder listen over mappenavn som Python importerer moduler fra. Legg merke til at den første strengen i sys.path er tom – denne tomme strengen indikerer at mappen programmet befinner seg i også er en del av sys.path, som er det samme som PYTHONPATH-miljøvariabelen. Dette betyr at du kan importere moduler som er i samme mapper direkte. Hvis ikke må du plassere modulen din i en av mappene som er skrevet opp i sys.path.

Byte-kompilerte .pyc-filer

Å importere en modul er en ganske kostbar affære, så Python gjør noen triks for å gjøre det raskere. En måte er å lage byte-kompilerte filer med filutvidelsen .pyc, som er en mellomform som Python gjør programmet om til (husker du introduksjonsdelen om hvordan Python virker?). .pyc-filen er nyttig neste gang du importerer modulen fra et annet program – det vil være langt raskere siden en del av arbeidet allerede er gjort. Byte-kompilerte filer virker også på tvers av plattformer.

Bemerkning
.pyc-filen lagres vanligvis i samme mappe som den tilsvarende .py-filen deres. Hvis Python ikke har tillatelse til å skrive filer til mappen lages det ikke noen .pyc-fil.

from … import …-påstanden

Hvis du vil importere argv-variabelen direkte inn i programmet (for å unngå å skrive sys. hver eneste gang) kan du bruke påstanden from sys import argv. Hvis du vil importere alle navnene fra sys-modulen, kan du bruke påstanden from sys import *. Dette virker på alle moduler.

Du bør unngå å bruke slike påstander og heller bruke import-påstanden, siden det vil forhindre kollisjoner mellom navn i programmet og modulen og gjøre programmet ditt lettere å lese.

En moduls __name__

Alle moduler har et navn, og påstander inni en modul kan finne ut navnet på modulen sin. Dette er hendig dersom du vil finne ut om modulen kjøres for seg selv eller har blitt importert. Som vi har nevnt før, kjører man hovedblokken i en modul første gang man importerer den. Dette kan vi bruke for å kjøre blokken bare om programmet kjører for seg selv, og ikke når det har blitt importert fra en annen modul. Dette gjør vi ved å bruke __name__-attributtet til en modul.

Eksempel:

#!/usr/bin/python
# Filnavn: bruke_name.py

if __name__ == '__main__':
    print('Programmet kjører for seg selv')
else:
    print('Jeg blir importert fra en annen modul')

Output:

   $ python bruke_name.py
   Programmet kjører for seg selv

   $ python
   >>> import bruke_name
   Jeg blir importert fra en annen modul
   >>>

Hvordan det virker:

Hver eneste Python-modul har definert __name__-et sitt, og hvis dette er '__main__' betyr det at modulen kjøres for seg selv av brukeren og at vi kan handle ut fra dette.

Lage sine egne moduler

Å lage sine egne moduler er lett, du har gjort det hele tiden! Dette er fordi alle Python-programmer også er moduler. Du må bare sørge for at det har en .py-filutvidelse. Det følgende eksempelet gjør det nok klart for deg.

Eksempel:

#!/usr/bin/python
# Filnavn: minmodul.py

def sihei():
    print('Hei, dette er minmodul som snakker.')

__versjon__ = '0.1'

# Slutten på minmodul.py

Dette var en prøvemodul. Som du kan se er det ikke noe spesielt med den sammenlignet med de vanlige programmene våre. Vi skal se på hvordan vi bruker denne modulen i de andre programmene våre.

Husk på at modulen bør ligge i samme mappe som programmet vi importerer den i, ellers burde den ligge i en av mappene som er skrevet opp i sys.path.

#!/usr/bin/python
# Filnavn: minmodul_demo.py

import minmodul

minmodul.sihei()
print ('Versjon', minmodul.__versjon__)

Output:

   $ python mymodule_demo.py
   Hei, dette er minmodul som snakker.
   Versjon 0.1

Hvordan det virker:

Legg merke til at vi bruker punktum i notasjonen for å bruke deler av modulen, akkurat som før. Python bruker den samme notasjonen når vi har med moduler å gjøre for å gi deg en god ‘pytonisk’ følelse; du trenger ikke å måtte lære mange nye måter å gjøre ting på.

Her er en versjon som bruker from..import-syntaksen:

#!/usr/bin/python
# Filnavn: minmodul_demo2.py

from minmodul import sihei, __versjon__
# Alternativt:
# From minmodul import *

sihei()
print('Versjon', __versjon__)

Outputen til minmodul_demo2.py er den samme som outputen til minmodul_demo.py.

Legg merke til at hvis det allerede var erklært et __versjon__-navn i modulen som importerer minmodul, ville vi fått en konflikt mellom navnene. Det er også svært sannsynlig at dett vil skje, siden det er en vanlig skikk å erklære versjonsnummeret inni en modul med dette navnet. Derfor anbefaler man å bruke import-påstanden, selv om det gjør programmet ditt litt lengre.

Python-zen
Ett av Pythons prinsipper er at “Uttrykt er bedre enn inneforstått”. Kjør import this for å lære mer.

dir-funksjonen

Du kan bruke den innebygde dir-funksjonen for å liste opp alle identifikatorene som et objekt definerer. For eksempel kan alle identifikatorene i en modul være funksjonene, klassene og variablene som er definert inni modulen.

Når du gir dir()-funksjonen et navn på en modul, gir den tilbake en liste med navnene som er definert inni den modulen. Når du ikke gir den noen argumenter, gir den tilbake en liste med navn som er definert inni den aktive modulen.

Eksempel:

$ python

>>> import sys # få en liste med attributter, i dette tilfellet fra sys-modulen

>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', '__s
tderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_compact_freelists',
'_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', '
byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle'
, 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable',
'exit', 'flags', 'float_info', 'getcheckinterval', 'getdefaultencoding', 'getfil
esystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof',
 'gettrace', 'getwindowsversion', 'hexversion', 'intern', 'maxsize', 'maxunicode
', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platfor
m', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_in
fo', 'warnoptions', 'winver']

>>> dir() # få liste med attributter for den aktive modulen
['__builtins__', '__doc__', '__name__', '__package__', 'sys']

>>> a = 5 # lag en ny variabel 'a'

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'sys']

>>> del a # slett/fjern a-navnet
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']

>>>

Hvordan det virker:

Først ser vi på hvordan man bruker dirsys-modulen som vi har importert. Vi får se den lange listen over attributter som den inneholder.

Så bruker vi dir-funksjonen uten å gi den noen parametre. Da gir den tilbake listen med attributter for den aktive modulen. Legg merke til at modulene vi har importert også er en del av listen.

For å se på dir i aksjon definerer vi en ny variabel a og gir den en verdi. Så sjekker vi dir og får se at det har kommet enda en verdi i listen. Vi tar vekk variabelen/attributtet i modulen ved å bruke del-påstanden, og denne forandringen kan man også se i outputen fra dir-funksjonen.

En bemerkning om del – denne påstanden brukes for å slette en variabel/et navn, og etter at Python har kjørt påstanden kan man ikke få tilgang til variabelen a igjen – det er som om den ikke en gang fantes.

Legg merke til at dir()-funksjonen virker på alle objekter. For eksempel, kjør dir(print) for å lære om attributtene til print-funksjonen, eller dir(str) for å få attributtene til str-klassen.

Pakker

Nå har du nok oppdaget hierarkiet i hvordan programmer er organisert. Variabler ligger vanligvis inni funksjoner. Funksjoner og globale variabler ligger vanligvis inni moduler. Hva hvis du har lyst til å organisere moduler? Her kommer pakker inn i bildet.

Pakker er bare mapper med moduler med en spesiell __init__.py-fil som indikerer for Python at mappen er spesiell fordi den inneholder Python-moduler.

La oss si at du ville lage en pakke med navnet ‘verden’, med underpakkene ‘asia’, ‘europa’ og så videre, og disse underpakkene igjen inneholder moduler som ‘india’, ‘norge’ og så videre.

Slik strukturerer du mappene dine:

   - <en eller annen mappe fra sys.path>/
       - verden/
           - __init__.py
           - asia/
               - __init__.py
               - india/
                   - __init__.py
                   - foo.py
           - europa/
               - __init__.py
               - norge/
                   - __init__.py
                   - bar.py

Pakker er bare noe man gjør for bekvemmelighetens skyld og for å kunne organisere modulene hierarkisk. Du skal få se mange eksempler på dette i kapitlet om standardbiblioteket.

Sammendrag

Akkurat som funksjoner er deler av programmer du kan bruke om igjen er moduler programmer du kan bruke om igjen. Pakker er enda et hierarki for å organisere moduler. Standardbiblioteket som kommer med Python er et eksempel på et slikt sett med pakker og moduler.

Vi har sett på hvordan vi kan bruke disse modulene og lage våre egne.

Nå skal vi lære om noen interessante konsepter, kalt datastrukturer.


Advertisements