https://docs.python.org/3/library/importlib.html
importlib - The implementation of 'import'.
PEP 302 - New Import Hooks.
Python pozwala umieszczać pożyteczne definicje obiektów oraz instrukcje w osobnym pliku zwanym modułem. Możemy importować definicje z danego mudułu do innych modułów lub do modułu głównego, czy trybu interaktywnego. Jeżeli nazwa modułu to abc, to nazwa pliku modułu ma postać abc.py. Wewnątrz modułu jego nazwa dostępna jest jako wartość zmiennej globalnej __name__.
Import modułu tworzy przestrzeń nazw, a zmienne zdefiniowane na najwyższym poziomie pliku modułu stają się atrybutami zaimportowanego obiektu modułu. Inaczej mówiąc, zakres globalny pliku modułu staje się po zaimportowaniu przestrzenią nazw atrybutów obiektu modułu.
Podstawowa rola modułów:
Program napisany w Pythonie składa się z pliku najwyższego poziomu (moduł główny) wraz z zero lub większą liczbą plików modułów dodatkowych.
Podstawowe instrukcje związane z modułami to import oraz from. Funkcja związana z modułami to reload(). Zwyczajowo instrukcje import umieszcza się na początku modułu. Zalecane jest umieszczanie każdego importu w osobnym wierszu.
W Pythonie 3 wszystkie mechanizmy związane z importowaniem modułów są zawarte w bibliotece importlib. Biblioteka importlib jest używana do dynamicznego importu modułów, a także w sytuacji, gdy nazwa modułu nie jest znana w czasie pisania kodu (wtyczki, rozszerzenia aplikacji).
Kod modułu jest wykonywany tylko raz podczas pierwszego importu. Python wykonuje instrukcje modułu jedna po drugiej, od góry pliku do dołu. Zwykle instrukcje wewnątrz modułu służą do jego inicjalizacji. Importowany moduł może z kolei importować inne moduły.
# Zastosowanie instrukcji import. import module1 # zaleca się pojedyńcze zapisy import module2, module3 # import kilku modułów print(module1.name1) # kwalifikacja zmiennej z modułu other_name = module1 # przypisanie obiektu modułu print(other_name.name1) module1.name1 = new_value # zwykle dozwolone, ale ostrożnie! print(module1.name2()) # kwalifikacja funkcji z modułu print(module1.__doc__) # dostęp do łańcucha dokumentacyjnego help(module1) # NAME, FILE, FUNCTIONS, DATA dir(module1) # przestrzeń nazw module1.__dict__.keys() # przestrzeń nazw
# Zastosowanie instrukcji 'from'. from module1 import name1, name2 # ładowanie wybranych nazw # Równoważne instrukcje są następujące: # import module1 # name1 = module1.name1 # name2 = module1.name2 # del module1 from module2 import * # ładowanie wszystkich nazw print(name1, name2()) # nie ma kwalifikacji
import module1 as module2 # import modułu pod inną nazwą # Równoważne instrukcje są następujące: # import module1 # module2 = module1 # del module1 import numpy as np import Tkinter as tk # Py2 import tkinter as tk # Py3 import pygame as pg
from module3 import name1 as name2 # zmiana nazw atrybutów
# Ponowne ładowanie modułu. #reload(module1) # Py2 import importlib importlib.reload(module1) # Py3.4+
Instrukcja from niszczy podział przestrzeni nazw, ponieważ nazwy są importowane bezpośrednio do lokalnej tablicy symboli. Sama nazwa modułu, z którego importowane są nazwy, nie jest ustawiana. Beztroskie korzystanie z instrukcji from grozi nadpisaniem istniejących zmiennych z lokalnego zakresu. Inne problemy mogą pojawić się przy zastosowaniu reload(). Generalnie zalecane jest stosowanie instrukcji import.
Dostęp do przestrzeni nazw modułu odbywa się za pomocą atrybutu __dict__ lub dir(module). Inaczej mówiąc, funkcja wbudowana dir() pozwala dowiedzieć się jakie nazwy są zdefiniowane przez moduł.
Python automatycznie zawiera wielki zbiór modułów narzędzi znany pod nazwą biblioteki standardowej. Są one zwykle dostępne tam, gdzie można uruchomić Pythona.
Przy pierwszym imporcie danego pliku przez program wykonywane są trzy osobne kroki.
Python przechowuje moduły programu w słowniku sys.modules.
import sys print(sys.modules.keys()) # nazwy importowanych modułów print(sys.path) # ścieżka wyszukiwania
Zestawienie tych czterech komponentów staje się sys.path (lista nazw katalogów, lista stringów).
Do funkcji reload() przekazuje się istniejący obiekt modułu, który wcześniej został zaimportowany. Przeładowanie oferuje możliwość modyfikowania działających programów bez zatrzymywania ich. Dzięki temu można skrócić cykl programowania.
Funkcja reload() wykonuje nowy kod pliku modułu w bieżącej przestrzeni nazw modułu. Funkcja modyfikuje obiekt modułu IN PLACE. Przeładowanie nie ma wpływu na kod, który wcześniej wykorzystał instrukcję from - pozostaną referencje do starych obiektów.
# Korzystanie z funkcji exec(). module_name = "string" exec("import " + module_name)
# Korzystanie z __import__ (do użytku przez interpreter i w Pythonie 2). module_name = "string" string = __import__(module_name)
# Programistyczny import modułu (Py3.1+). # importlib.import_module(name, package=None) import importlib module_name = "string" string = importlib.import_module(module_name)
Załóżmy, że nasz program składa się z modułu głównego main.py, który importuje moduł spam z pliku spam.py. Przy pierwszym uruchomieniu naszego programu kod z pliku spam.py jest kompilowany do bytecode i zapisywany do pliku spam.pyc, którego zawartość jest niezależna od platformy. Przy następnym uruchomieniu naszego programu kod modułu spam jest wczytywany bezpośrednio z pliku spam.pyc, dzięki czemu program uruchamia się szybciej. Jeżeli czas modyfikacji pliku spam.py nie zgadza się z czasem zapisanym w pliku spam.pyc, to plik spam.pyc jest ignorowany.
Przy normalnej pracy nie ma potrzeby zajmować się plikami .pyc. Czasem rozpowszechnia się biblioteki Pythona w postaci plików .pyc, aby utrudnić poznanie ich kodu. Ponadto czasem można spotkać pliki z rozszerzeniem .pyo które oznacza, że interpreter Pythona został uruchomiony w trybie optymalizacji z flagą -O.