Python 3 Modules

Python

O modułach

Moduł pozwala na logiczne uporządkowanie kodu Pythona. Grupowanie powiązanego kodu w moduł czyni kod łatwiejszym do zrozumienia i użycia. Moduł to obiekt w języku Python z arbitralnie nazwanymi atrybutami, które można powiązać i odwoływać się. Po prostu moduł jest plikiem składającym się z kodu Pythona. Może definiować funkcje, klasy i zmienne. Również  może zawierać działający kod.
W Pythonie moduły są po prostu plikami z rozszerzeniem .py, w których zawarto pewien zestaw funkcji. Moduły importujemy do swojego programu za pomocą komendy import.

Stwórzmy mały moduł dla lepszego zobrazowania. Tworzymy plik modul.py:

#!/usr/bin/env python 3
# -*- coding: utf-8 -*-

def witaj(imię):
    print(f"Witaj {imię}")

 

Uruchomienie modul.py jako programu wykonywalnego nie spowoduje żadnego widocznego skutku, funkcja witaj w prawdzie została zdefiniowana, ale program zakończy działanie zanim zostanie w ogóle użyta (wywołana). Wykorzystaliśmy tutaj metodę .format w skróconej wersji, spowoduje to przypisanie do {imię}, atrybutu imienia z funkcji witaj, które przypiszemy przy wywoływaniu w nowym pliku uruchamiającym. Zatem stwórzmy teraz drugi plik uruchamiający powitanie.py.

#!/usr/bin/env python 3
# -*- coding: utf-8 -*-

import modul

modul.witaj("Franek")

Przez import modul informujemy Pythona o przeszukiwaniu modułów pod kątem słowa modul, jeśli nie znajdzie w swojej bibliotece zaczyna przeszukiwanie w katalogu, w którym wykonywany jest plik. Następną linię czytamy mniej więcej tak: „Z modułu modul weź funkcję witaj i dopisz argument „Franek„.
W rezultacie mamy nazwa_modulu.nazwa_funkcji(), gdzie za nazwę_funkcji() możemy wstawić nazwę klasy lub zmiennej. Kropka pomiędzy to dowiązanie do modułu, podobnie jak w klasach, gdy tworzyliśmy instancję, np. JakasKlasa.dodawanie().

Żeby to lepiej zobrazować zróbmy jeszcze jeden moduł i go wywołajmy.

modul.py:


def dodawanie(x, y):
    print("Wynik dodawania: ", x + y)

def odejmowanie(x, y):
    print("Wynik odejmowania: ", x - y)

zmienna = "Zmienna1"
zmienna1 = 20

calc.py:


import modul

modul.dodawanie(2, 3)
modul.odejmowanie(10, 3)

print(modul.zmienna)
print(modul.zmienna1)

 

Trzy sposoby importu

Zaznajomiliśmy się z prostym importowaniem modułu za pomocą impor modul, który wskazuje bezpośrednio na moduł. W Pythonie mamy również inny sposób, który realizuje tę samą czynność, ale posiada pewne różnice. Poniżej został przedstawiony przykład wykorzystujący instrukcję from module import:

from apihelper import info

Jak widzimy, składnia tego wyrażenia jest bardzo podobna do import module, ale z jedną ważną różnicą: atrybuty i metody danego modułu są importowane bezpośrednio do lokalnej przestrzeni nazw, a więc będą dostępne bezpośrednio i nie musimy określać,z którego modułu korzystamy. Żeby zauważyć różnicę spójrzmy na poniższy przykład:

>>> import types
>>> types.FunctionType                    #(1)
<type 'function'>
>>>
>>> FunctionType                          #(2)
Traceback (most recent call last):File "", 
line 1, in ?NameError: name ’FunctionType’ is not defined
>>>
>>> from types import FunctionType        #(3)
>>> FunctionType                          #(4)
<type ’function’> 
  1. Moduł types nie posiada żadnych metod. Posiada on jedynie atrybuty określające wszystkie typy zdefiniowane przez Pythona. Zauważmy, że atrybut tego modułu (w tym przypadku FunctionType) musi być poprzedzony nazwą modułu types.
  2. FunctionType nie został sam w sobie określony w przestrzeni nazw; istnieje on tylko w kontekście modułu types.
  3. Za pomocą tego wyrażenia atrybut FunctionType z modułu types został zaimportowany bezpośrednio do lokalnej przestrzeni nazw.
  4. Teraz możemy odwoływać się bezpośrednio do FunctionType, bez odwoływania się do types.

Kiedy korzystać z from module import:

  • W momencie gdy często odwołujemy się do atrybutów i metod, a nie chcemy wielokrotnie wpisywać nazwy modułu, wtedy najlepiej wykorzystać from module import.
  • Jeśli potrzebujemy selektywnie zaimportować tylko kilka atrybutów lub metod.
  • Jeśli moduł zawiera atrybuty lub metody, które posiadają taką samą nazwę jaka jest w naszym module, powinniśmy wykorzystać import module, aby uniknąć konfliktu nazw.

W innych przypadkach to kwestia stylu programowania, można spotkać oba na raz w jednym projekcie.

Ostatnim sposobem jest importowanie wszystkich metod danego modułu:

from module import *

Jednak należy używać go ostrożnie ponieważ utrudnia on określenie, skąd pochodzi dana funkcja lub atrybut, a to zaś utrudnia debugowanie programu.

Testowanie modułów

Moduły Pythona to obiekty, które posiadają kilka przydatnych atrybutów. Możemyich użyć do łatwego testowania własnych modułów. Oto przykład zastosowania triku if  __name__:

if __name__ == "__main__":

Należy zwrócić uwagę że instrukcja if nie wymaga nawiasów i kończy się dwukropkiem a w następnej linii znajduje się wcięty kod.
Na czym polega zastosowany trik? Moduły to obiekty, a każdy z nich posiada wbudowany atrybut __name__, który zależy od tego, w jaki sposób korzystamy z danego modułu. Jeżeli importujemy moduł, wtedy __name__ jest nazwą pliku modułu bez ścieżki do katalogu, czy rozszerzenia pliku. Możemy także uruchomić bezpośrednio moduł jako samodzielny program, a wtedy __name__ przyjmie domyślną wartość  „__main__„.
Wiedząc o tym, możemy zaprojektować test wewnątrz swojego modułu, wykorzystując do tego instrukcję if. Jeśli uruchomisz bezpośrednio dany moduł, atrybut name jest równy „main” , a więc test zostanie wykonany. Podczas importu tego modułu, name przyjmie inną wartość, więc test się nie uruchomi. Pomoże nam to rozwijać i wyszukiwać błędy w programie (czyli debugować), zanim dany moduł zintegrujemy z większym programem.

>>> import odbchelper
>>> odbchelper.__name__
’odbchelper’

Dodaj komentarz