Articles

Hvad Er Python Navnerum (Og Hvorfor Er De Nødvendige?)

navnekonflikter sker hele tiden i det virkelige liv. For eksempel, hver skole, jeg nogensinde gik på, havde mindst to studerende i min klasse, der delte det samme fornavn. Hvis nogen kom ind i klassen og bad om studerende, ville vi entusiastisk spørge: “hvilken taler du om? “Derefter ville den spørgende give os et efternavn, og vi ville introducere ham til højre.

al denne forvirring og processen med at bestemme den nøjagtige person, vi taler om ved at lede efter andre oplysninger udover et fornavn, kunne undgås, hvis alle havde et unikt navn. Dette er ikke et problem i en klasse på 30 studerende. Det bliver dog stadig vanskeligere at komme med et unikt, meningsfuldt og let at huske navn for hvert barn i en skole, by, by, land eller hele verden. Et andet problem ved at give hvert barn et unikt navn er, at processen med at bestemme, om en anden også har navngivet deres barn Macey, Maci eller Macie kunne være meget trættende.

en meget lignende konflikt kan også opstå i programmeringen. Når du skriver et program på kun 30 linjer uden eksterne afhængigheder, er det meget nemt at give unikke og meningsfulde navne til alle dine variabler. Problemet opstår, når der er tusindvis af linjer i et program, og du har også indlæst nogle eksterne moduler. I denne vejledning lærer du om navneområder, deres betydning og omfangsopløsning i Python.

Hvad er navnerum?

et navneområde er dybest set et system til at sikre, at alle navne i et program er unikke og kan bruges uden nogen konflikt. Du ved måske allerede, at alt i Python—lignende strenge, lister, funktioner osv.- er et objekt. En anden interessant kendsgerning er, at Python implementerer navnerum som ordbøger. Der er en navn-til-objekt-kortlægning med navnene som nøgler og objekterne som værdier. Flere navneområder kan bruge det samme navn og knytte det til et andet objekt. Her er et par eksempler på navneområder:

  • lokalt navneområde: Dette navneområde indeholder lokale navne inde i en funktion. Dette navneområde oprettes, når en funktion kaldes, og det varer kun, indtil funktionen vender tilbage.
  • globalt navneområde: dette navneområde indeholder navne fra forskellige importerede moduler, som du bruger i et projekt. Det oprettes, når modulet er inkluderet i projektet, og det varer, indtil scriptet slutter.
  • indbygget navneområde: dette navneområde indeholder indbyggede funktioner og indbyggede undtagelsesnavne.

i de matematiske moduler i Python-serien på Envato Tuts+ skrev jeg om nyttige matematiske funktioner tilgængelige i forskellige moduler. For eksempel har math-og cmath-modulerne mange funktioner, der er fælles for dem begge, som log10()acos()cos()exp() osv. Hvis du bruger begge disse moduler i det samme program, er den eneste måde at bruge disse funktioner utvetydigt på at præfiksere dem med navnet på modulet, som math.log10() og cmath.log10().

Hvad er Scope?

navneområder hjælper os med entydigt at identificere alle navne i et program. Dette betyder dog ikke, at vi kan bruge et variabelnavn hvor som helst vi ønsker. Et navn har også et omfang, der definerer de dele af programmet, hvor du kan bruge dette navn uden at bruge noget præfiks. Ligesom navneområder er der også flere anvendelsesområder i et program. Her er en liste over nogle anvendelsesområder, der kan eksistere under udførelsen af et program.

  • et lokalt område, som er det inderste område, der indeholder en liste over lokale Navne, der er tilgængelige i den aktuelle funktion.
  • et omfang af alle de omsluttende funktioner. Søgningen efter et navn starter fra det nærmeste omsluttende omfang og bevæger sig udad.
  • et modulniveau, der indeholder alle de globale navne fra det aktuelle modul.
  • det yderste område, der indeholder en liste over alle de indbyggede navne. Dette omfang søges sidst for at finde det navn, du refererede til.

i de kommende afsnit af denne tutorial vil vi i vid udstrækning bruge den indbyggede Python dir ()-funktion til at returnere en liste med navne i det aktuelle lokale omfang. Dette vil hjælpe dig med at forstå begrebet navnerum og omfang mere tydeligt.

Omfangsopløsning

som jeg nævnte i det foregående afsnit, starter søgningen efter et givet navn fra den inderste funktion og bevæger sig derefter højere og højere, indtil programmet kan kortlægge dette navn til et objekt. Når der ikke findes et sådant navn i nogen af navneområderne, rejser programmet en undtagelse fra NameError.

før vi begynder, prøv at skrivedir() i tomgang eller enhver anden Python IDE.

dir()# 

lad os se udgangen afdir() funktion efter at have defineret en variabel og en funktion.

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

dir() funktionen udsender kun listen over navne inden for det aktuelle omfang. Derfor er der inden for omfanget af some_func() kun et navn kaldet b_num. Opkald dir() efter at have defineret some_func() tilføjer det til listen over Navne, der er tilgængelige i det globale navneområde.

lad os nu se listen over navne inde i nogle indlejrede funktioner. Koden i denne blok fortsætter fra den foregående blok.

ovenstående kode definerer to variabler og en funktion inden for omfanget afouter_func(). Inde inner_func()dir() funktionen udskriver kun navnet d_num. Dette virker retfærdigt, da d_num er den eneste variabel, der er defineret derinde.

medmindre det udtrykkeligt er angivet ved hjælp afglobal, genplacering af et globalt navn i et lokalt navneområde opretter en ny lokal variabel med samme navn. Dette fremgår af følgende kode.

inde i både outer_func() og inner_func()a_num er blevet erklæret for at være en global variabel. Vi sætter bare en anden værdi for den samme globale variabel. Dette er grunden til, at værdien af a_num på alle steder er 20. På den anden side opretter hver funktion sin egen b_num variabel med et lokalt omfang, og print() funktion udskriver værdien af denne lokalt scoped variabel.

korrekt import af moduler

det er meget almindeligt at importere eksterne moduler i dine projekter for at fremskynde udviklingen. Der er tre forskellige måder at importere moduler på. I dette afsnit lærer du om alle disse metoder og diskuterer deres fordele og ulemper i detaljer.

  • from module import *: Denne metode til import af et modul importerer alle navne fra det givne modul direkte i dit nuværende navneområde. Du kan blive fristet til at bruge denne metode, fordi den giver dig mulighed for at bruge en funktion direkte uden at tilføje navnet på modulet som et præfiks. Det er dog meget fejlbehæftet, og du mister også evnen til at fortælle hvilket modul der faktisk importerede denne funktion. Her er et eksempel på at bruge denne metode:

Hvis du er bekendt med math-og cmath-modulerne, ved du allerede, at der er et par almindelige navne, der er defineret i begge disse moduler, men gælder for henholdsvis reelle og komplekse tal.

da vi har importeret CMATH-modulet efter matematikmodulet, overskriver det funktionsdefinitionerne af disse fælles funktioner fra matematikmodulet. Dette er grunden til, at den første log10(125) returnerer et reelt tal, og det andet log10(125) returnerer et komplekst tal. Der er ingen måde for dig at bruge log10() – funktionen fra matematikmodulet nu. Selvom du forsøgte at skrive math.log10(125), får du en NameError undtagelse, fordi math findes faktisk ikke i navneområdet.

den nederste linje er, at du ikke bør bruge denne måde at importere funktioner fra forskellige moduler bare for at gemme et par tastetryk.

  • from module import nameA, nameB: hvis du ved, at du kun skal bruge et eller to navne fra et modul, kan du importere dem direkte ved hjælp af denne metode. På denne måde kan du skrive koden mere kortfattet, mens du stadig holder navneområdets forurening til et minimum. Husk dog, at du stadig ikke kan bruge noget andet navn fra modulet ved at bruge module.nameZ. Enhver funktion, der har samme navn i dit program, overskriver også definitionen af den funktion, der importeres fra modulet. Dette vil gøre den importerede funktion ubrugelig. Her er et eksempel på at bruge denne metode:
dir()# from math import log2, log10dir()# log10(125)# 2.0969100130080562
  • import module: dette er den sikreste og anbefalede måde at importere et modul på. Den eneste ulempe er, at du bliver nødt til at præfiksere navnet på modulet til alle de Navne, du skal bruge i programmet. Du vil dog være i stand til at undgå namespace forurening og også definere funktioner, hvis navne matcher navnet på funktioner fra modulet.
dir()# import mathdir()# math.log10(125)# 2.0969100130080562

Endelige tanker

Jeg håber, at denne tutorial hjalp dig med at forstå navnerum og deres betydning. Du skal nu være i stand til at bestemme omfanget af forskellige navne i et program og undgå potentielle faldgruber.

tøv ikke med at se, hvad vi har til salg og til undersøgelse på markedet, og tøv ikke med at stille spørgsmål og give din værdifulde feedback ved hjælp af feedet nedenfor.

det sidste afsnit af artiklen diskuterede forskellige måder at importere moduler i Python og fordele og ulemper ved hver af dem. Hvis du har spørgsmål relateret til dette emne, så lad mig det vide i kommentarerne.

Lær Python

Lær Python med vores komplette python tutorial guide, Uanset om du lige er kommet i gang, eller du er en erfaren koder, der ønsker at lære nye færdigheder.