Articles

Czym Są Przestrzenie Nazw Pythona (I Dlaczego Są Potrzebne?)

konflikty nazw zdarzają się cały czas w prawdziwym życiu. Na przykład, każda szkoła, do której chodziłem, miała przynajmniej dwóch uczniów w mojej klasie, którzy mieli to samo imię. Gdyby ktoś przyszedł do klasy i poprosił o ucznia X, z entuzjazmem zapytalibyśmy: „o którym mówisz? Jest dwóch uczniów o imieniu X. ” Po tym, pytająca osoba podałaby nam nazwisko, a my wprowadzilibyśmy go do właściwego X.

całego tego zamieszania i procesu określania dokładnej osoby, o której mówimy, poprzez szukanie innych informacji oprócz imienia, można było uniknąć, gdyby każdy miał unikalne imię. To nie jest problem w klasie 30 uczniów. Jednak coraz trudniej będzie wymyślić unikalne, znaczące i łatwe do zapamiętania imię dla każdego dziecka w szkole, mieście, mieście, kraju lub na całym świecie. Inną kwestią w nadaniu każdemu dziecku unikalnego imienia jest to, że proces ustalania, czy ktoś inny również nazwał swoje dziecko Macey, Maci lub Macie, może być bardzo męczący.

bardzo podobny konflikt może powstać również w programowaniu. Kiedy piszesz program składający się z zaledwie 30 linijek bez zewnętrznych zależności, bardzo łatwo jest nadać unikalne i znaczące nazwy wszystkim zmiennym. Problem pojawia się, gdy w programie są tysiące linii i załadowałeś również niektóre zewnętrzne moduły. W tym samouczku dowiesz się o przestrzeniach nazw, ich znaczeniu i rozdzielczości zakresu w Pythonie.

czym są przestrzenie nazw?

przestrzeń nazw jest w zasadzie systemem, aby upewnić się, że wszystkie nazwy w programie są unikalne i mogą być używane bez konfliktu. Być może już wiesz, że wszystko w Pythonie—jak ciągi, listy, funkcje, itp.- jest przedmiotem. Innym interesującym faktem jest to, że Python implementuje przestrzenie nazw jako słowniki. Istnieje mapowanie nazwy obiektu, z nazwami jako kluczami, a obiektami jako wartościami. Wiele przestrzeni nazw może używać tej samej nazwy i mapować ją do innego obiektu. Oto kilka przykładów przestrzeni nazw:

  • lokalna Przestrzeń nazw: Ta przestrzeń nazw zawiera nazwy lokalne wewnątrz funkcji. Ta przestrzeń nazw jest tworzona podczas wywoływania funkcji i trwa tylko do jej powrotu.
  • globalna Przestrzeń nazw: ta przestrzeń nazw zawiera nazwy z różnych zaimportowanych modułów, których używasz w projekcie. Jest tworzony, gdy moduł jest zawarty w projekcie i trwa do zakończenia skryptu.
  • Wbudowana Przestrzeń nazw: ta przestrzeń nazw zawiera wbudowane funkcje i wbudowane nazwy WYJĄTKÓW.

w serii Mathematical Modules in Python na Envato Tuts+ pisałem o przydatnych funkcjach matematycznych dostępnych w różnych modułach. Na przykład Moduły math i cmath mają wiele funkcji wspólnych dla obu z nich, takich jak log10()acos()cos()exp() itd. Jeśli używasz obu tych modułów w tym samym programie, jedynym sposobem na jednoznaczne użycie tych funkcji jest dodanie prefiksu z nazwą modułu, na przykład math.log10() I cmath.log10().

Co To jest Scope?

Przestrzenie nazw pomagają nam jednoznacznie zidentyfikować wszystkie nazwy wewnątrz programu. Nie oznacza to jednak, że możemy używać nazwy zmiennej gdziekolwiek chcemy. Nazwa ma również zakres, który określa części programu, w których można użyć tej nazwy bez użycia żadnego prefiksu. Podobnie jak przestrzenie nazw, istnieje również wiele zakresów w programie. Oto lista niektórych zakresów, które mogą istnieć podczas wykonywania programu.

  • lokalny zakres, który jest najbardziej wewnętrznym zakresem, który zawiera listę lokalnych nazw dostępnych w bieżącej funkcji.
  • zakres wszystkich funkcji załączających. Wyszukiwanie nazwy zaczyna się od najbliższego obszaru otaczającego i przesuwa się na zewnątrz.
  • zakres poziomu modułu, który zawiera wszystkie globalne nazwy z bieżącego modułu.
  • zewnętrzny zakres zawierający listę wszystkich wbudowanych nazw. Ten zakres jest przeszukiwany jako ostatni, aby znaleźć nazwę, do której się odwołałeś.

w nadchodzących sekcjach tego samouczka będziemy Szeroko używać wbudowanej funkcji Python dir (), aby zwrócić listę nazw w bieżącym lokalnym zasięgu. Pomoże Ci to lepiej zrozumieć pojęcie przestrzeni nazw i zakresu.

rozdzielczość zakresu

jak wspomniałem w poprzedniej sekcji, Wyszukiwanie danej nazwy zaczyna się od funkcji innermost, a następnie przesuwa się coraz wyżej, aż program może odwzorować tę nazwę na obiekt. Jeśli taka nazwa nie zostanie znaleziona w żadnej z przestrzeni nazw, program tworzy wyjątek NameError.

zanim zaczniemy, spróbuj wpisać dir() w IDLE lub innym Python IDE.

dir()# 

zobaczmy wyjście funkcjidir() po zdefiniowaniu zmiennej i funkcji.

a_num = 10dir()# def some_func(): b_num = 11 print(dir()) some_func()# dir()# 

funkcja dir() wyświetla tylko listę nazw wewnątrz bieżącego zakresu. Dlatego wewnątrz zakresu some_func() istnieje tylko jedna nazwa o nazwie b_num. Wywołanie dir() po zdefiniowaniu some_func() dodaje go do listy nazw dostępnych w globalnej przestrzeni nazw.

teraz, zobaczmy listę nazw wewnątrz niektórych funkcji zagnieżdżonych. Kod w tym bloku jest kontynuowany z poprzedniego bloku.

powyższy kod definiuje dwie zmienne i funkcję wewnątrz zakresu outer_func(). Wewnątrz inner_func(), funkcja dir() wypisuje tylko nazwę d_num. Wydaje się to sprawiedliwe, ponieważ d_num jest jedyną zdefiniowaną zmienną.

o ile nie podano jawnie za pomocąglobal, ponowne przypisanie nazwy globalnej wewnątrz lokalnej przestrzeni nazw tworzy nową zmienną lokalną o tej samej nazwie. Wynika to z poniższego kodu.

wewnątrzouter_func() Iinner_func()a_num został zadeklarowany jako zmienna globalna. Po prostu ustawiamy inną wartość dla tej samej zmiennej globalnej. Z tego powodu wartość a_num we wszystkich lokalizacjach wynosi 20. Z drugiej strony, każda funkcja tworzy własną zmiennąb_num o lokalnym zasięgu, a funkcjaprint() wypisuje wartość tej zmiennej o lokalnym zasięgu.

poprawne Importowanie modułów

bardzo często importuje się zewnętrzne moduły w projektach, aby przyspieszyć rozwój. Istnieją trzy różne sposoby importowania modułów. W tej sekcji dowiesz się o wszystkich tych metodach, szczegółowo omawiając ich zalety i wady.

  • from module import * : Ta metoda importowania modułu importuje wszystkie nazwy z podanego Modułu bezpośrednio w bieżącej przestrzeni nazw. Możesz pokusić się o użycie tej metody, ponieważ pozwala ona na bezpośrednie użycie funkcji bez dodawania nazwy modułu jako prefiksu. Jednak jest to bardzo podatne na błędy, a także tracisz możliwość określenia, który moduł faktycznie zaimportował tę funkcję. Oto przykład zastosowania tej metody:

Jeśli znasz Moduły math i cmath, wiesz już, że istnieje kilka wspólnych nazw, które są zdefiniowane w obu tych modułach, ale odnoszą się odpowiednio do liczb rzeczywistych i zespolonych.

ponieważ zaimportowaliśmy moduł cmath po module matematycznym, nadpisuje on definicje funkcji tych wspólnych funkcji z modułu matematycznego. Dlatego pierwszy log10(125)Zwraca liczbę rzeczywistą, a drugilog10(125) Zwraca liczbę złożoną. Nie ma możliwości użycia funkcjilog10() z modułu matematycznego. Nawet jeśli spróbujesz wpisać math.log10(125), otrzymasz wyjątek NameError, ponieważ math w rzeczywistości nie istnieje w przestrzeni nazw.

najważniejsze jest to, że nie należy używać tego sposobu importowania funkcji z różnych modułów tylko po to, aby zapisać kilka naciśnięć klawiszy.

  • from module import nameA, nameB: jeśli wiesz, że będziesz używać tylko jednej lub dwóch nazw z modułu, możesz zaimportować je bezpośrednio za pomocą tej metody. W ten sposób możesz napisać kod bardziej zwięźle, jednocześnie ograniczając zanieczyszczenie przestrzeni nazw do minimum. Należy jednak pamiętać, że nadal nie można użyć żadnej innej nazwy z modułu, używając module.nameZ. Każda funkcja, która ma tę samą nazwę w programie, nadpisze również definicję tej funkcji importowanej z modułu. Spowoduje to, że zaimportowana funkcja będzie bezużyteczna. Oto przykład użycia tej metody:
dir()# from math import log2, log10dir()# log10(125)# 2.0969100130080562
  • import module: jest to najbezpieczniejszy i zalecany sposób importowania modułu. Jedynym minusem jest to, że będziesz musiał przedrostek nazwy modułu do wszystkich nazw, które masz zamiar użyć w programie. Będziesz jednak w stanie uniknąć zanieczyszczenia przestrzeni nazw, a także zdefiniować funkcje, których nazwy pasują do nazw funkcji z modułu.
dir()# import mathdir()# math.log10(125)# 2.0969100130080562

myśli końcowe

mam nadzieję, że ten poradnik pomógł Ci zrozumieć przestrzenie nazw i ich znaczenie. Powinieneś teraz być w stanie określić zakres różnych nazw w programie i uniknąć potencjalnych pułapek.

ponadto, nie wahaj się zobaczyć, co mamy dostępne w sprzedaży i do nauki na rynku, i nie wahaj się zadawać żadnych pytań i przekazać swoją cenną opinię za pomocą kanału poniżej.

w końcowej części artykułu omówiono różne sposoby importowania modułów w Pythonie oraz zalety i wady każdego z nich. Jeśli masz jakieś pytania związane z tym tematem, daj mi znać w komentarzach.

Ucz się Pythona

Ucz się Pythona z naszym kompletnym przewodnikiem po Pythonie, niezależnie od tego, czy dopiero zaczynasz, czy jesteś doświadczonym programistą, który chce nauczyć się nowych umiejętności.