Historia pytania
Namespaces (przestrzenie nazw) to jedna z podstawowych koncepcji Pythona, obecna już od pierwszych realizacji języka. Służy do systematyzacji nazw, aby uniknąć konfliktów między zmiennymi, funkcjami i klasami w różnych częściach programu.
Problem
W dużych projektach pojawia się wiele funkcji, klas, zmiennych i modułów. Bez poprawnego użycia namespaces możliwe jest nadpisanie ważnych nazw, uzyskanie nieoczekiwanych cieni zmiennych i trudności w testowaniu oraz rozszerzaniu.
Rozwiązanie
W Pythonie namespace to odwzorowanie (mapping), które łączy nazwy z obiektami. Istnieją różne poziomy przestrzeni nazw: lokalne, globalne, przestrzenie modułów, klas. Zrozumienie takiego podziału gwarantuje prawidłowe odniesienie do potrzebnych obiektów i minimalizację konfliktów.
Przykład kodu:
def foo(): x = 10 # x w lokalnej przestrzeni nazw funkcji print(x) y = 20 # y w globalnej przestrzeni nazw modułu foo() print(y)
Kluczowe cechy:
Co się stanie, jeśli w tej samej funkcji zadeklarujemy lokalną zmienną o tej samej nazwie co globalna?
Lokalna "przykryje" globalną podczas wykonywania funkcji; poza funkcją globalna pozostanie niezmieniona.
a = 1 def test(): a = 2 print(a) # 2 test() print(a) # 1
Jak uzyskać listę wszystkich nazw w bieżącej przestrzeni nazw?
Funkcje locals(), globals(), dir() zwracają odpowiednie odwzorowania lub listy nazw w bieżącym zakresie/namespace.
Czym się różnią przestrzenie nazw klas i instancji?
Przestrzeń nazw klasy definiuje atrybuty wspólne dla wszystkich instancji klasy. Przestrzeń nazw instancji — atrybuty konkretnego obiektu. Zmiany w instancji nie wpływają na klasę i odwrotnie.
Użyto from mymodule import * we wszystkich częściach dużego projektu. W rezultacie nazwy funkcji uległy zamazaniu, pojawiły się trudne do uchwycenia błędy z powodu konfliktów nazw między pakietami.
Zalety:
Wady:
Przeszliśmy na aliasy importów (import mymodule as mm), jasna struktura modułów.
Zalety:
Wady: