Python-modules: Je code organiseren voor duidelijkheid en herbruikbaarheid
Een module stelt je in staat om je Python-code logisch te organiseren. Door gerelateerde code in een module te groeperen, wordt de code eenvoudiger te begrijpen en te gebruiken. Een module is een Python-object willekeurig benamde attributen die je kunt binden en refereren.
Eenvoudig gezegd is een module een bestand bestaande uit Python-code. Een module kan functies, klassen en variabelen definiëren. Een module kan ook uitvoerbare code bevatten.
Voorbeeld
De Python-code voor een module met de naam aname bevindt zich normaal in een bestand met de naam aname.py. Hier is een voorbeeld van een eenvoudige module, support.py:
def print_func(par):
print("Hallo : ", par)
return
De import-instructie
Je kunt elk Python-bronbestand als een module gebruiken door een import-instructie uit te voeren in een ander Python-bronbestand. De import heeft de volgende syntaxis:
import module1[, module2[,... moduleN]]
Wanneer de interpreter een import-instructie tegenkomt, importeert het de module als deze aanwezig is in het zoekpad. Een zoekpad is een lijst met mappen die de interpreter doorzoekt voordat het een module importeert. Om bijvoorbeeld de module support.py te importeren, moet je de volgende opdracht bovenaan het script plaatsen:
#!/usr/bin/python
# Importeer module support
import support
# Nu kun je de gedefinieerde functie van die module als volgt aanroepen
support.print_func("Zara")
Wanneer de bovenstaande code wordt uitgevoerd, produceert dit het volgende resultaat:
Hallo : Zara
Een module wordt maar één keer geladen, ongeacht hoe vaak het geïmporteerd wordt. Dit voorkomt dat de module-executie herhaaldelijk plaatsvindt als er meerdere imports optreden.
De from...import-instructie
Python's from-instructie laat je specifieke attributen uit een module importeren in de huidige naamruimte. De from...import heeft de volgende syntaxis:
from modname import name1[, name2[, ... nameN]]
Bijvoorbeeld, om de functie fibonacci uit de module fib te importeren, gebruik je de volgende instructie:
from fib import fibonacci
Deze instructie importeert niet de gehele module fib in de huidige naamruimte; het introduceert alleen het item fibonacci uit de module fib in de globale symbooltabel van de importeerende module.
De from...import *-instructie
Het is ook mogelijk om alle namen uit een module in de huidige naamruimte te importeren met behulp van de volgende import-instructie:
from modname import *
Dit biedt een gemakkelijke manier om alle items uit een module in de huidige naamruimte te importeren; deze instructie moet echter spaarzaam worden gebruikt.
Modules lokaliseren
Wanneer je een module importeert, zoekt de Python-interpreter de module in de volgende volgorde:
De huidige map.
Als de module niet gevonden wordt, zoekt Python vervolgens in elke map in de shell-variabele PYTHONPATH.
Als alles faalt, controleert Python het standaardpad. Op UNIX is dit standaardpad normaal /usr/local/lib/python/.
Het module-zoekpad wordt opgeslagen in de systeemmodule sys als de variabele sys.path. De variabele sys.path bevat de huidige map, PYTHONPATH en de installatie-afhankelijke standaard.
De PYTHONPATH-variabele
De PYTHONPATH is een omgevingsvariabele, bestaande uit een lijst met mappen. De syntaxis van PYTHONPATH is dezelfde als die van de shell-variabele PATH.
Hier is een typische PYTHONPATH van een Windows-systeem:
set PYTHONPATH = c:\python20\lib;
En hier is een typische PYTHONPATH van een UNIX-systeem:
set PYTHONPATH = /usr/local/lib/python
Naamruimtes en bereik
Variabelen zijn namen (identificators) die op objecten wijzen. Een naamruimte is een woordenboek van variabelennamen (sleutels) en hun bijbehorende objecten (waarden).
Een Python-instructie kan variabelen benaderen in een lokale naamruimte en in de globale naamruimte. Als een lokale en een globale variabele dezelfde naam hebben, schaduwt de lokale variabele de globale variabele.
Elke functie heeft zijn eigen lokale naamruimte. Klasmethodes volgen dezelfde bereikregels als gewone functies.
Python maakt weloverwogen gokken over of variabelen lokaal of globaal zijn. Het gaat ervan uit dat elke variabele waaraan een waarde wordt toegewezen in een functie lokaal is.
Daarom moet je, om een waarde toe te wijzen aan een globale variabele binnen een functie, eerst de global-instructie gebruiken.
De instructie global VarName vertelt Python dat VarName een globale variabele is. Python stopt met zoeken in de lokale naamruimte naar de variabele.
Bijvoorbeeld, we definiëren een variabele Money in de globale naamruimte. Binnen de functie Money wijzen we Money een waarde toe, dus Python gaat ervan uit dat Money een lokale variabele is. Echter, we hebben de waarde van de lokale variabele Money benaderd voordat we het instelden, wat resulteert in een UnboundLocalError. Het uncommenten van de global-instructie lost het probleem op.
#!/usr/bin/python
Money = 2000
def AddMoney():
# Uncomment de volgende regel om de code te repareren:
# global Money
Money = Money + 1
print(Money)
AddMoney()
print(Money)
De dir()-functie
De ingebouwde functie dir() retourneert een gesorteerde lijst van strings met de namen die door een module gedefinieerd zijn.
De lijst bevat de namen van alle modules, variabelen en functies die in een module gedefinieerd zijn. Hier is een eenvoudig voorbeeld:
#!/usr/bin/python # Importeer ingebouwde module math import math content = dir(math) print(content)
Wanneer de bovenstaande code wordt uitgevoerd, produceert dit het volgende resultaat:
['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
Hier is de speciale stringvariabele __name__ de naam van de module, en __file__ is de bestandsnaam waaruit de module geladen werd.
De globals() en locals()-functies
De globals() en locals()-functies kunnen worden gebruikt om de namen in de globale en lokale naamruimtes terug te geven, afhankelijk van de locatie waar ze worden aangeroepen.
Als locals() wordt aangeroepen vanuit een functie, retourneert het alle namen die lokaal vanuit die functie benaderd kunnen worden.
Als globals() wordt aangeroepen vanuit een functie, retourneert het alle namen die globaal vanuit die functie benaderd kunnen worden.
Het retourtype van beide functies is een woordenboek. Daarom kunnen namen worden geëxtraheerd met behulp van de keys()-functie.
De reload()-functie
Wanneer de module in een script wordt geïmporteerd, wordt de code in het top-level gedeelte van een module slechts één keer uitgevoerd.
Daarom, als je de top-level code in een module opnieuw wilt uitvoeren, kun je de reload()-functie gebruiken. De reload()-functie importeert een eerder geïmporteerde module opnieuw. De syntaxis van de reload()-functie is:
reload(module_naam)
Hier is module_naam de naam van de module die je wilt herladen en niet de string die de modulenaam bevat. Bijvoorbeeld, om de hello-module te herladen, doe je het volgende:
reload(hello)
Pakketten in Python
Een pakket is een hiërarchische bestandsmapstructuur die een enkele Python-toepassingsomgeving definieert die bestaat uit modules en subpakketten en sub-subpakketten, enzovoort.
Overweeg een bestand Pots.py beschikbaar in de Phone-map. Dit bestand heeft de volgende regel broncode:
#!/usr/bin/python
def Pots():
print("Ik ben Pots Phone")
Op dezelfde manier hebben we nog twee bestanden met verschillende functies met dezelfde naam als hierboven:
Phone/Isdn.py bestand met functie Isdn()
Phone/G3.py bestand met functie G3()
Maak nu nog een bestand __init__.py in de Phone-map:
- Phone/__init__.py
Om al je functies beschikbaar te maken wanneer je Phone importeert, moet je expliciete import-instructies in __init__.py zetten als volgt:
from Pots import Pots from Isdn import Isdn from G3 import G3
Nadat je deze regels aan __init__.py hebt toegevoegd, heb je al deze klassen beschikbaar wanneer je het Phone-pakket importeert.
#!/usr/bin/python # Importeer nu je Phone-pakket. import Phone Phone.Pots() Phone.Isdn() Phone.G3()
Wanneer de bovenstaande code wordt uitgevoerd, produceert dit het volgende resultaat:
Ik ben Pots Phone Ik ben 3G Phone Ik ben ISDN Phone
In het bovenstaande voorbeeld hebben we een voorbeeld genomen van een enkele functie in elk bestand, maar je kunt meerdere functies in je bestanden bewaren. Je kunt ook verschillende Python-klassen in die bestanden definiëren en dan je pakketten daraus maken.
Python
- Python Datatypes onder de knie krijgen: Een praktische gids
- Python I/O en Module Imports onder de knie krijgen: Een praktische gids
- Python Operators onder de knie krijgen: Een uitgebreide gids
- Python Functie-argumenten onder de knie krijgen: Positionele, Keyword en Default Parameters
- Python Modules: Aanmaken, Importeren en Geavanceerd Gebruik
- Python-dictionaries beheersen: aanmaken, manipuleren en geavanceerde technieken
- Python-iterators: hoe ze werken en hoe je je eigen maakt
- Python-closures uitgelegd: hoe geneste functies variabelen vangen
- Python datetime beheersen: praktische gids voor datums, tijden en tijdzones
- Python's time-module beheersen: functies, structs en praktische voorbeelden
- Python's time.sleep() onder de knie krijgen: best practices, multithreading en real-world voorbeelden