Korzystanie z modułów

https://docs.python.org/3/library/importlib.html
importlib - The implementation of 'import'.

PEP 302 - New Import Hooks.

WPROWADZENIE

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:

ARCHITEKTURA PROGRAMU W PYTHONIE

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.

JAK DZIAŁA IMPORTOWANIE

Przy pierwszym imporcie danego pliku przez program wykonywane są trzy osobne kroki.

  1. Odnalezienie pliku modułu (wykorzystanie standardowej ścieżki wyszukiwania modułów).
  2. Skompilowanie go do kodu bajtowego, jeśli jest to konieczne (powstają pliki .pyc).
  3. Wykonanie kodu modułu w celu utworzenia zdefiniowanych przez niego obiektów.

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

ŚCIEŻKA WYSZUKIWANIA MODUŁÓW

  1. Katalog główny programu.
  2. Katalogi ze zmiennej środowiskowej PYTHONPATH (jeśli są ustawione).
  3. Katalogi biblioteki standardowej (zależne od instalacji).
  4. Zawartość wszystkich plików .pth (jeśli są obecne).

Zestawienie tych czterech komponentów staje się sys.path (lista nazw katalogów, lista stringów).

PRZEŁADOWYWANIE MODUŁÓ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.

IMPORTOWANIE MODUŁÓW ZA POMOCĄ ŁAŃCUCHA NAZWY


# 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)

"SKOMPILOWANE" PLIKI PYTHONA

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.