6. Moduler¶
Om du avslutar Python-tolken och öppnar den igen går de definitioner du har gjort (funktioner och variabler) förlorade. Om du vill skriva ett lite längre program är det därför bättre att använda en textredigerare för att förbereda indata till tolken och köra den med den filen som indata istället. Detta kallas att skapa ett skript. När programmet blir längre kan det vara bra att dela upp det i flera filer för att underlätta underhållet. Du kanske också vill använda en praktisk funktion som du har skrivit i flera program utan att kopiera dess definition till varje program.
För att stödja detta har Python ett sätt att lägga definitioner i en fil och använda dem i ett skript eller i en interaktiv instans av tolken. En sådan fil kallas för en modul; definitioner från en modul kan importeras till andra moduler eller till huvudmodulen (den samling variabler som du har tillgång till i ett skript som körs på toppnivå och i kalkylatorläge).
En modul är en fil som innehåller Python-definitioner och -satser. Filnamnet är modulnamnet med suffixet .py
tillagt. Inom en modul är modulens namn (som en sträng) tillgängligt som värdet på den globala variabeln __name__
. Använd till exempel din favorittextredigerare för att skapa en fil med namnet fibo.py
i den aktuella katalogen med följande innehåll:
# Fibonacci numbers module
def fib(n):
"""Write Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n):
"""Return Fibonacci series up to n."""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
Gå nu in i Python-tolken och importera denna modul med följande kommando:
>>> import fibo
Detta lägger inte till namnen på de funktioner som definieras i fibo
direkt till den aktuella namespace (se Python Scopes och namnrymder för mer information); det lägger bara till modulnamnet fibo
där. Med hjälp av modulnamnet kan du komma åt funktionerna:
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Om du tänker använda en funktion ofta kan du tilldela den ett lokalt namn:
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
6.1. Mer om moduler¶
En modul kan innehålla såväl körbara satser som funktionsdefinitioner. Dessa satser är avsedda att initiera modulen. De körs endast första gången modulnamnet påträffas i en importsats. [1] (De körs också om filen exekveras som ett skript.)
Varje modul har sitt eget privata namnrymd, som används som globalt namnrymd av alla funktioner som definieras i modulen. På så sätt kan författaren till en modul använda globala variabler i modulen utan att behöva oroa sig för oavsiktliga kollisioner med en användares globala variabler. Om du vet vad du gör kan du å andra sidan använda samma notation för modulens globala variabler som för dess funktioner, modname.itemname
.
Moduler kan importera andra moduler. Det är brukligt men inte nödvändigt att placera alla import
-satser i början av en modul (eller ett skript, för den delen). De importerade modulnamnen läggs till modulens globala namnrymd om de placeras på modulens översta nivå (utanför funktioner eller klasser).
Det finns en variant av import
-satsen som importerar namn från en modul direkt till den importerande modulens namnrymd. Till exempel:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Detta introducerar inte modulnamnet från vilket importen hämtas i det lokala namnrymden (så i exemplet är fibo
inte definierat).
Det finns till och med en variant för att importera alla namn som en modul definierar:
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Detta importerar alla namn utom de som börjar med ett understreck (_
). I de flesta fall använder Python-programmerare inte denna funktion eftersom den introducerar en okänd uppsättning namn i tolken, vilket kan dölja vissa saker som du redan har definierat.
Observera att det i allmänhet är ogillat att importera *
från en modul eller ett paket, eftersom det ofta leder till dåligt läsbar kod. Det är dock okej att använda det för att spara in på skrivandet i interaktiva sessioner.
Om modulnamnet följs av as
, så är namnet som följer efter as
bundet direkt till den importerade modulen.
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Detta innebär att modulen importeras på samma sätt som import fibo
, med den enda skillnaden att den är tillgänglig som fib
.
Det kan också användas när man använder from
med liknande effekter:
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Anteckning
Av effektivitetsskäl importeras varje modul bara en gång per tolksession. Om du ändrar dina moduler måste du därför starta om tolken – eller, om det bara är en modul som du vill testa interaktivt, använda importlib.reload()
, t.ex. import importlib; importlib.reload(modulename)
.
6.1.1. Exekvera moduler som skript¶
När du kör en Python-modul med
python fibo.py <arguments>
kommer koden i modulen att exekveras, precis som om du importerade den, men med __name__
satt till "__main__"
. Det betyder att genom att lägga till den här koden i slutet av din modul:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
kan du göra filen användbar både som ett skript och som en importerbar modul, eftersom koden som analyserar kommandoraden bara körs om modulen körs som ”huvudfilen”:
$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34
Om modulen är importerad körs inte koden:
>>> import fibo
>>>
Detta används ofta antingen för att ge ett bekvämt användargränssnitt till en modul eller för teständamål (om modulen körs som ett skript körs en testsvit).
6.1.2. Sökvägen för moduler¶
När en modul med namnet spam
importeras, söker tolken först efter en inbyggd modul med samma namn. Dessa modulnamn finns listade i sys.builtin_module_names
. Om den inte hittas söker den efter en fil med namnet spam.py
i en lista över kataloger som anges av variabeln sys.path
. sys.path
initialiseras från dessa platser:
Den katalog som innehåller inmatningsskriptet (eller den aktuella katalogen om ingen fil har angetts).
PYTHONPATH
(en lista med katalognamn, med samma syntax som skalvariabelnPATH
).Den installationsberoende standardinställningen (enligt konvention inklusive en katalog med
site-packages
, som hanteras av modulensite
).
Mer information finns på Initialisering av sökvägen för modulen sys.path.
Anteckning
På filsystem som stöder symbollänkar beräknas katalogen som innehåller indataskriptet efter att symbollänken har följts. Med andra ord läggs katalogen som innehåller symbollänken inte till i sökvägen för modulen.
Efter initialisering kan Python-program ändra sys.path
. Den katalog som innehåller det skript som körs placeras i början av sökvägen, före standardbibliotekets sökväg. Detta innebär att skript i den katalogen kommer att laddas istället för moduler med samma namn i bibliotekskatalogen. Detta är ett fel om inte ersättningen är avsedd. Se avsnitt Standardmoduler för mer information.
6.1.3. ”Kompilerade” Python-filer¶
För att påskynda laddning av moduler cachar Python den kompilerade versionen av varje modul i katalogen __pycache__
under namnet module.version.pyc`
, där versionen kodar formatet för den kompilerade filen; den innehåller vanligtvis Pythons versionsnummer. Till exempel, i CPython version 3.3 skulle den kompilerade versionen av spam.py cachelagras som __pycache__/spam.cpython-33.pyc
. Denna namngivningskonvention gör det möjligt för kompilerade moduler från olika utgåvor och olika versioner av Python att samexistera.
Python kontrollerar källans ändringsdatum mot den kompilerade versionen för att se om den är föråldrad och behöver kompileras om. Detta är en helt automatisk process. De kompilerade modulerna är dessutom plattformsoberoende, så samma bibliotek kan delas mellan system med olika arkitekturer.
Python kontrollerar inte cacheminnet under två omständigheter. För det första kompilerar den alltid om och lagrar inte resultatet för den modul som laddas direkt från kommandoraden. För det andra kontrolleras inte cacheminnet om det inte finns någon källmodul. För att stödja en distribution utan källkod (endast kompilerad) måste den kompilerade modulen finnas i källkatalogen och det får inte finnas någon källkodsmodul.
Några tips för experter:
Du kan använda switcharna
-O
eller-OO
på Python-kommandot för att minska storleken på en kompilerad modul. Med-O
tas assert-satser bort, med-OO
tas både assert-satser och __doc__-strängar bort. Eftersom vissa program kan vara beroende av att ha dessa tillgängliga, bör du bara använda det här alternativet om du vet vad du gör. ”Optimerade” moduler har taggenopt-
och är vanligtvis mindre. Framtida utgåvor kan ändra effekterna av optimeringen.Ett program körs inte snabbare när det läses från en
.pyc
-fil än när det läses från en.py
-fil; det enda som är snabbare med.pyc
-filer är den hastighet med vilken de laddas.Modulen
compileall
kan skapa .pyc-filer för alla moduler i en katalog.Det finns mer information om denna process, inklusive ett flödesschema över besluten, i PEP 3147.
6.2. Standardmoduler¶
Python levereras med ett bibliotek av standardmoduler, som beskrivs i ett separat dokument, Python Library Reference (”Library Reference” hädanefter). Vissa moduler är inbyggda i tolken; dessa ger tillgång till operationer som inte är en del av kärnan i språket men som ändå är inbyggda, antingen för effektivitet eller för att ge tillgång till operativsystemets primitiver såsom systemanrop. Uppsättningen av sådana moduler är ett konfigurationsalternativ som också beror på den underliggande plattformen. Modulen winreg
finns till exempel bara på Windows-system. En särskild modul förtjänar lite uppmärksamhet: sys
, som är inbyggd i alla Python-tolkar. Variablerna sys.ps1
och sys.ps2
definierar de strängar som används som primär och sekundär uppmaning:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
Dessa två variabler definieras endast om tolken befinner sig i interaktivt läge.
Variabeln sys.path
är en lista med strängar som bestämmer tolkens sökväg för moduler. Den initialiseras till en standardsökväg som hämtas från miljövariabeln PYTHONPATH
, eller från en inbyggd standardsökväg om PYTHONPATH
inte är angiven. Du kan ändra den med hjälp av standard listoperationer:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
6.3. Funktionen dir()
¶
Den inbyggda funktionen dir()
används för att ta reda på vilka namn en modul definierar. Den returnerar en sorterad lista med strängar:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
'__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
'warnoptions']
Utan argument listar dir()
de namn som du har definierat för närvarande:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
Observera att den listar alla typer av namn: variabler, moduler, funktioner etc.
dir()
listar inte namnen på inbyggda funktioner och variabler. Om du vill ha en lista över dessa finns de definierade i standardmodulen builtins
:
>>> import builtins
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
'zip']
6.4. Paket¶
Paket är ett sätt att strukturera Pythons modulnamnrymd genom att använda ”prickade modulnamn”. Till exempel, modulnamnet A.B
betecknar en undermodul med namnet B
i ett paket med namnet A
. Precis som användningen av moduler gör att författarna till olika moduler inte behöver bekymra sig om varandras globala variabelnamn, gör användningen av prickade modulnamn att författarna till multimodulpaket som NumPy eller Pillow inte behöver bekymra sig om varandras modulnamn.
Anta att du vill utforma en samling moduler (ett ”paket”) för enhetlig hantering av ljudfiler och ljuddata. Det finns många olika ljudfilformat (som vanligtvis känns igen på filtillägget, t.ex. .wav
, .aiff
, .au
), så du kan behöva skapa och underhålla en växande samling moduler för konvertering mellan olika filformat. Det finns också många olika operationer som du kan vilja utföra på ljuddata (t.ex. mixa, lägga till eko, använda en equalizerfunktion, skapa en artificiell stereoeffekt), så du kommer dessutom att skriva en aldrig sinande ström av moduler för att utföra dessa operationer. Här är en möjlig struktur för ditt paket (uttryckt i termer av ett hierarkiskt filsystem):
sound/ Paket på högsta nivå
__init__.py Initiera ljudpaketet
formats/ Underpaket för konvertering av filformat
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Underpaket för ljudeffekter
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Underförpackning för filter
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
Vid import av paketet söker Python igenom katalogerna på sys.path
och letar efter paketets underkatalog.
Filerna __init__.py
krävs för att Python ska behandla kataloger som innehåller filen som paket (om inte namespace package används, vilket är en relativt avancerad funktion). Detta förhindrar att kataloger med ett gemensamt namn, t.ex. string
, oavsiktligt döljer giltiga moduler som finns längre fram i sökvägen för moduler. I det enklaste fallet kan __init__.py
bara vara en tom fil, men den kan också exekvera initialiseringskod för paketet eller ställa in variabeln __all__
, som beskrivs senare.
Användare av paketet kan importera enskilda moduler från paketet, till exempel:
importera sound.effects.echo
Detta laddar undermodulen sound.effects.echo
. Den måste refereras till med sitt fullständiga namn.
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
Ett alternativt sätt att importera undermodulen är:
från sound.effects importera echo
Detta laddar också undermodulen echo
och gör den tillgänglig utan dess paketprefix, så att den kan användas på följande sätt:
echo.echofilter(input, output, delay=0,7, atten=4)
Ytterligare en variant är att importera den önskade funktionen eller variabeln direkt:
från sound.effects.echo importera echofilter
Återigen laddar detta undermodulen echo
, men detta gör dess funktion echofilter()
direkt tillgänglig:
ekofilter(ingång, utgång, fördröjning=0,7, atten=4)
Observera att när du använder from package import item
kan objektet vara antingen en undermodul (eller ett underpaket) i paketet eller något annat namn som definieras i paketet, t.ex. en funktion, klass eller variabel. Satsen import
testar först om objektet är definierat i paketet; om inte, antar den att det är en modul och försöker ladda den. Om den inte hittar den, utlöses ett ImportError
-undantag.
Om man däremot använder en syntax som import item.subitem.subsubitem
måste varje objekt utom det sista vara ett paket; det sista objektet kan vara en modul eller ett paket men kan inte vara en klass, funktion eller variabel som definieras i det föregående objektet.
6.4.1. Importera * från ett paket¶
Vad händer nu när användaren skriver from sound.effects import *
? Idealiskt sett skulle man hoppas att detta på något sätt går ut i filsystemet, hittar vilka undermoduler som finns i paketet och importerar dem alla. Detta kan ta lång tid och import av undermoduler kan ha oönskade bieffekter som bara bör ske när undermodulen uttryckligen importeras.
Den enda lösningen är att paketets författare tillhandahåller ett explicit index för paketet. Satsen import
använder följande konvention: om ett pakets kod __init__.py
definierar en lista med namnet __all__
, anses den vara listan över modulnamn som ska importeras när from package import *
påträffas. Det är upp till paketets författare att hålla denna lista uppdaterad när en ny version av paketet släpps. Paketförfattare kan också besluta att inte stödja det, om de inte ser någon användning för att importera * från sitt paket. Till exempel kan filen sound/effects/__init__.py
innehålla följande kod:
__all__ = ["echo", "surround", "reverse"]
Detta skulle innebära att from sound.effects import *
skulle importera de tre namngivna undermodulerna i paketet sound.effects
.
Var medveten om att undermoduler kan bli skuggade av lokalt definierade namn. Om du till exempel lägger till en funktion reverse
i filen sound/effects/__init__.py`
, kommer from sound.effects import *
bara att importera de två undermodulerna echo
och surround
, men inte undermodulen reverse
, eftersom den skuggas av den lokalt definierade funktionen reverse
:
__all__ = [
"echo", # hänvisar till filen 'echo.py'
"surround", # refererar till filen "surround.py
"reverse", # !!! hänvisar till funktionen "reverse" nu !!!
]
def reverse(msg: str): # <-- det här namnet skuggar undermodulen 'reverse.py'
return msg[::-1] # i fallet med en 'from sound.effects import *'
Om __all__
inte är definierad, kommer uttalandet from sound.effects import *
inte att importera alla undermoduler från paketet sound.effects
till det aktuella namnrymden; det säkerställer bara att paketet sound.effects
har importerats (eventuellt körs någon initialiseringskod i __init__.py
) och importerar sedan alla namn som definieras i paketet. Detta inkluderar alla namn som definieras (och undermoduler som laddas explicit) av __init__.py
. Det inkluderar också alla undermoduler i paketet som uttryckligen laddades genom tidigare import
-satser. Tänk på den här koden:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
I det här exemplet importeras modulerna echo
och surround
i det aktuella namnrymden eftersom de definieras i paketet sound.effects
när from...import
-satsen körs. (Detta fungerar även när __all__
är definierat)
Även om vissa moduler är utformade för att endast exportera namn som följer vissa mönster när du använder import *
, anses det fortfarande vara dålig praxis i produktionskod.
Kom ihåg att det inte är något fel med att använda from package import specific_submodule
! I själva verket är detta den rekommenderade notationen om inte den importerande modulen behöver använda undermoduler med samma namn från olika paket.
6.4.2. Referenser inom förpackningen¶
När paket är strukturerade i underpaket (som med paketet sound
i exemplet) kan du använda absolut import för att hänvisa till undermoduler i syskonpaket. Om till exempel modulen sound.filters.vocoder
behöver använda modulen echo
i paketet sound.effects
kan den använda from sound.effects import echo
.
Du kan också skriva relativ import med import-satsen from module import name
. Dessa importer använder ledande prickar för att ange det aktuella och överordnade paket som är involverat i den relativa importen. Från modulen surround
kan du till exempel använda:
from . import echo
from .. import formats
from ..filters import equalizer
Observera att relativ import baseras på namnet på den aktuella modulens paket. Eftersom huvudmodulen inte har något paket, måste moduler som är avsedda att användas som huvudmodul i en Python-applikation alltid använda absolut import.
6.4.3. Paket i flera kataloger¶
Paket stöder ytterligare ett specialattribut, __path__
. Denna initialiseras till att vara en sekvens av strängar som innehåller namnet på den katalog som innehåller paketets __init__.py
innan koden i den filen exekveras. Variabeln kan ändras, men detta påverkar framtida sökningar efter moduler och underpaket som ingår i paketet.
Den här funktionen behövs inte ofta, men den kan användas för att utöka uppsättningen moduler i ett paket.
Fotnoter