Trumpas apimties nustatymo taisyklių aprašymas?

Kas tiksliai yra „Python“ domeno taisyklės?

Jei turiu kodą:

 code1 class Foo: code2 def spam..... code3 for code4..: code5 x() 

Kur yra x ? Kai kurie galimi variantai yra žemiau pateiktas sąrašas:

  1. Pridedamame šaltinio faile
  2. Klasės vardų erdvėje
  3. Funkcijos apibrėžime
  4. Kintamojo indekso kintamajame
  5. Viduje kilpa

Runtime taip pat yra kontekstas, kai spam funkcija perduodama kitur. O gal lambda funkcijos šiek tiek skiriasi?

Kažkur turi būti paprasta nuoroda ar algoritmas. Tai vidutinis lygio „Python“ programuotojų susipynęs pasaulis.

415
15 нояб. nustatė Charles Merriam lapkričio 15 d 2008-11-15 04:48 '08, 4:48, 2008-11-15 04:48
@ 7 atsakymai

Tiesą sakant, trumpa taisyklė, leidžianti „Python Scope“, nuo „ Python“ mokymosi, 3. „Edition“ (šios taisyklės taikomos kintamųjų pavadinimams, o ne atributams. Jei nurodote juos be taško, šios taisyklės taikomos)

LEGB taisyklė.

L , Vietiniai - vardai, priskirti funkcijai ( def arba lambda ), kurie šioje funkcijoje nėra paskelbti visuotiniais.

E , vietiniai-vietiniai funkcionalai - bet kokių statiškai įgalinančių funkcijų ( def ar lambda ) vietinė apimtis, nuo vidinės iki išorinės.

G , Global (modulis) - pavadinimai, priskirti viršutiniame modulio failo lygmenyje, arba vykdant global instrukcijas failo viduje.

B , Built-in (Python) - Vardai, anksčiau priskirti integruotam pavadinimo moduliui: open , range , „ SyntaxError , ...

Taigi

 code1 class Foo: code2 def spam..... code3 for code4..: code5 x() 

„For“ kilpa neturi savo vardų erdvės. LEGB tvarka bus vietovės

L: vietinis, def spam ( code 4 , code 4 , code 4 ).

E: Asmeninė funkcija, bet kokios funkcijos (jei visas pavyzdys buvo kitame def )

G: Global. Ar x paskelbtas visame pasaulyje modulyje ( code1 )?

B: bet koks įdėtas x Python.

x niekada nebus rastas code2 (net ir tais atvejais, kai tikitės, žr. „ Antti“ atsakymą arba čia ).

375
15 нояб. Rizwan Kassim atsakymas lapkričio 15 d 2008-11-15 15:47 '08 at 15:47 2008-11-15 15:47

Tiesą sakant, vienintelis dalykas, esantis Pythone, kuriame pristatoma nauja sritis, yra funkcijos apibrėžimas. Klasės yra ypatingas atvejis, kai viskas, kas yra tiesiogiai apibrėžta organizme, yra įtraukta į klasės vardų erdvę, tačiau jie nėra tiesiogiai prieinami iš jų turimų metodų (ar įdėtų klasių).

Jūsų pavyzdyje yra tik 3 sritys, kuriose x ieškos:

  • šlamšto taikymo sritis - yra viskas, apibrėžta kodo 3 ir kodo 5 (taip pat kodo 4, jūsų kintamojo kodo)

  • Pasaulinis plotas - kuriame yra viskas, kas nurodyta kode1, taip pat „Foo“ (ir visi pakeitimai po jo)

  • Integruotų vardų erdvė. Mažai specialaus atvejo - jame yra įvairių įmontuotų funkcijų ir Python tipų, pvz., Len () ir str (). Paprastai tai neturėtų būti keičiama jokiu pasirinktiniu kodu, todėl tikimasi, kad jame bus standartinės funkcijos ir nieko daugiau.

Papildomos sritys rodomos tik tada, kai įdėtas įdėtas funkcija (arba lambda). Jie elgsis taip, kaip tikėjotės. Įdėta funkcija gali pasiekti visus vietinėje vietovėje esančius asmenis, taip pat viską, kas yra uždarymo funkcijoje. Pavyzdžiui.

 def foo(): x=4 def bar(): print x # Accesses x from foo scope bar() # Prints 4 x=5 bar() # Prints 5 

Apribojimai:

Prieiga prie kintamųjų vietovių, išskyrus vietinius funkcinius kintamuosius, bet negali būti atverti į naujus parametrus be sintaksės. Vietoj to, priskyrimas sukurs naują vietinį kintamąjį, o ne įtakos kintamajam tėvų srityje. Pavyzdžiui:

 global_var1 = [] global_var2 = 1 def func(): # This is OK: It just accessing, not rebinding global_var1.append(4) # This won't affect global_var2. Instead it creates a new variable global_var2 = 2 local1 = 4 def embedded_func(): # Again, this doen't affect func local1 variable. It creates a # new local variable also called local1 instead. local1 = 5 print local1 embedded_func() # Prints 5 print local1 # Prints 4 

Kad iš tikrųjų pakeistumėte pasaulinių kintamųjų susiejimus iš funkcijų srities, turite nurodyti, kad kintamasis yra pasaulinis su pasauliniu raktiniu žodžiu. Pavyzdžiui:

 global_var = 4 def change_global(): global global_var global_var = global_var + 1 

Šiuo metu nėra jokio būdo daryti tą patį kintamiesiems funkcijų srityse, tačiau „Python 3“ pristato naują „ nonlocal “ raktinį žodį, kuris veiks panašiai kaip ir pasaulinis, bet įdėtos funkcijos srityse.

142
16 нояб. Atsakymą pateikė Brian lapkričio 16 d. 2008-11-16 00:51 '08 at 0:51 2008-11-16 00:51

Nebuvo jokio išsamaus atsakymo dėl Python3 laiko, todėl atsakiau čia.

Kaip nurodyta kituose atsakymuose, yra keturios pagrindinės sritys: „LEGB“, „Vietos“, „Uždarymo“, „Global“ ir „Builtin“. Be to, yra speciali taikymo sritis, klasės kūnas , kuris neapima klasei būdingų metodų; bet kokie priskyrimai klasės kūnui daro kintamąjį iš ten, kuris yra priskirtas klasės kūnui.

Konkrečiai, jokios kitos nei def ir class bloko pareiškimai sukuria kintamą taikymo sritį. „Python 2“ sąrašo supratimas nesukuria kintamojo apimties, bet „Python 3“ kontūro kintamasis sukuriamas naujoje srityje.

Parodyti kūno klasės savybes

 x = 0 class X(object): y = x x = x + 1 # x is now a variable z = x def method(self): print(self.x) # -> 1 print(x) # -> 0, the global x print(y) # -> NameError: global name 'y' is not defined inst = X() print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0) 

Taigi, skirtingai nuo funkcijų kūno, galite keisti kintamąjį, turintį tą patį pavadinimą klasėje, kad gautumėte tokio paties pavadinimo klasės kintamąjį; vietoj klasės kintamojo leidžiama toliau ieškoti šio pavadinimo.


Vienas iš didžiausių Python naujokų netikėtumų yra tas, kad „ for loop“ nesukuria kintamos apimties. „Python 2“ sąrašo supratimas taip pat nesukuria taikymo srities (tuo tarpu generatoriai ir diktuojantys skaičiavimai tai daro!) Vietoj to, jie praleidžia vertę funkcijoje arba pasaulinėje srityje:

 >>> [ i for i in range(5) ] >>> i 4 

Supratimas gali būti naudojamas kaip sudėtingas (ar baisus, jei jums patinka) būdas sukurti keičiamuosius kintamuosius lambda išraiškose „Python 2“ - lambda išraiška sukuria kintamą taikymo sritį, kaip teigia def , bet jokie operatoriai neleidžiami lambda išraiškose. Užduotis, kuri yra „Python“ operatorius, reiškia, kad neleidžiami jokie priskyrimo kintamieji lambda, bet sąrašo supratimas yra išraiška ...

Šis elgesys buvo nustatytas „Python 3“ - nėra suprantamų išraiškų ar kintamų nuotėkio generatorių.


Pasaulinis iš tikrųjų reiškia modulio apimtį; Pagrindinis Python modulis yra __main__ ; visi importuoti moduliai yra prieinami per sys.modules kintamąjį; galite naudoti sys.modules['__main__'] arba import __main__ kad pasiektumėte import __main__ ; tai yra visiškai priimtina, kad būtų prieinami ir priskiriami atributai; jie bus rodomi kaip kintamieji pagrindiniame modulyje.


Jei pavadinimas kada nors priskirtas dabartinei sričiai (išskyrus klasę), jis bus laikomas priklausančiu šiai sričiai, kitaip jis bus laikomas priklausančiu bet kuriai sričiai, kuri priskiriama kintamajam (jis negali būti priskirtas). iki šiol arba ne) arba pagaliau pasauliniu mastu. Jei kintamasis yra laikomas vietiniu, bet jis dar nebuvo nustatytas arba buvo ištrintas, kintamojo vertės skaitymas sukels UnboundLocalError , kuris yra NameError poklasis.

 x = 5 def foobar(): print(x) # causes UnboundLocalError! x += 1 # because assignment here makes xa local variable within the function # call the function foobar() 

Apimtis gali pareikšti, kad ji aiškiai nori pakeisti pasaulinį kintamąjį (modulio taikymo sritį), naudojant bendrąjį raktinį žodį:

 x = 5 def foobar(): global x print(x) # -> 5 x += 1 foobar() print(x) # -> 6 

Tai taip pat įmanoma, net jei jis buvo užtamsintas pridedamoje srityje:

 x = 5 y = 13 def make_closure(): x = 42 y = 911 def func(): global x # sees the global value print(x, y) x += 1 return func func = make_closure() func() # -> print 5 911 print(x, y) # -> 6 13 

„Python 2“ nėra paprasto būdo keisti vertę viduje; tai paprastai modeliuojama su kintama verte, pvz., sąrašu, kurio ilgis yra 1:

 def make_closure(): value = [0] def get_next_value(): value[0] += 1 return value[0] return get_next_value get_next = make_closure() print(get_next()) # -> 1 print(get_next()) # -> 2 

Tačiau 3- nonlocal Python“ sistemoje „ nonlocal ateina į gelbėjimą:

 def make_closure(): value = 0 def get_next_value(): nonlocal value value += 1 return value return get_next_value get_next = make_closure() # identical behavior to the previous example. 

Bet koks kintamasis, kuris nėra laikomas vietiniu pagal dabartinę sritį arba kokią nors sritį, yra pasaulinis kintamasis. Visuotinis pavadinimas ieškomas modulio pasauliniame žodyne; jei jis nerastas, visuotinis objektas ieškomas iš įmontuoto modulio; modulio pavadinimas buvo pakeistas iš python 2 į python 3; 2 __builtin__ buvo __builtin__ o __builtin__ 3 dabar jis vadinamas builtins . Jei priskiriate inline moduliui atributą, jis bus matomas bet kuriam moduliui kaip skaitomas pasaulinis kintamasis, nebent šis modulis užfiksuotų savo pasaulinį kintamąjį tokiu pačiu pavadinimu.


Įterpto modulio skaitymas taip pat gali būti naudingas; Tarkime, kad kai kuriose failo dalyse jums reikia „Python 3“ stiliaus spausdinimo funkcijos, tačiau print ataskaita vis dar naudojama kitose failo dalyse. „Python 2.6-2.7“ galite gauti „Python 3“ print funkciją naudodami:

 import __builtin__ print3 = __builtin__.__dict__['print'] 

Funkcija „ from __future__ import print_function iš tikrųjų neimportuoja print funkcijos bet kurioje „Python 2“ vietoje - vietoj to ji paprasčiausiai išjungia print ataskaitos analizės taisykles dabartiniame modulyje, apdorodama print kaip ir bet kurį kitą kintamojo identifikatorių ir tokiu būdu leidžiant print funkcijai peržiūrėti paiešką integruotuose.

94
05 мая '14 в 14:08 2014-05-05 14:08 atsakymas duotas Antti Haapala 05 gegužės 14 d. 14:08 2014-05-05 14:08

„Python 2.x“ taikymo srities apibrėžimo taisyklės jau nustatytos kituose atsakymuose. Vienintelis dalykas, kurį norėčiau pridurti, yra tai, kad „Python 3.0“ yra ir ne vietinės teritorijos sąvoka (nurodoma raktažodžiais „ne vietos“). Tai leidžia tiesiogiai patekti į išorines sritis ir leidžia atlikti keletą tvarkingų gudrybių, įskaitant leksinius uždarymus (be bjaurių hack'ų, susijusių su pakeistais objektais).

EDIT: Čia yra PEP su daugiau informacijos apie tai.

21
15 нояб. atsakymą pateikė Jeremy Cantrell . 2008-11-15 21:52 '08 at 9:52 pm 2008-11-15 21:52

Šiek tiek išsamesnis vietovės pavyzdys:

 from __future__ import print_function # for python 2 support x = 100 print("1. Global x:", x) class Test(object): y = x print("2. Enclosed y:", y) x = x + 1 print("3. Enclosed x:", x) def method(self): print("4. Enclosed self.x", self.x) print("5. Global x", x) try: print(y) except NameError as e: print("6.", e) def method_local_ref(self): try: print(x) except UnboundLocalError as e: print("7.", e) x = 200 # causing 7 because has same name print("8. Local x", x) inst = Test() inst.method() inst.method_local_ref() 

išeiti:

20
04 дек. atsakymas pateikiamas brianray 04 dec. 2015-12-04 20:38 '15 ne 20:38 2015-12-04 20:38

„Python“ išsprendžia jūsų kintamuosius naudodamas tris galimas vardų vietas.

Bet kuriuo metu vykdymo metu yra bent trys įterpti domenai, kurių vardų sritys yra tiesiogiai prieinamos: slapčiausias paieškos domenas, kuris pirmą kartą buvo ieškomas, turi vietinius pavadinimus; bet kokių uždarymo funkcijų, kurių paieška prasideda artimiausia dengimo zona, vardų vietos; vidurinėje paieškos srityje šalia sąrašo yra dabartiniai pasaulio modulių pavadinimai; ir atokiausia sritis (paskutinis peržiūra) yra vardų sritis, kurioje yra integruoti pavadinimai.

Yra dvi funkcijos: globals ir locals , rodantys šių dviejų vardų turinį.

Vardų vietas sukuria paketai, moduliai, klasės, objektų konstrukcijos ir funkcijos. Kitų vardų erdvės skonių nėra.

Tokiu atveju funkcijų skambutis su pavadinimu x turi būti leidžiamas vietinėje vardų erdvėje arba pasaulinėje vardų erdvėje.

Šiuo atveju vietinis yra „ Foo.spam metodo funkcija.

Pasaulinis - pasaulinis.

Taisyklė yra ieškoti įdėtos vietinės erdvės, sukurtos metodo funkcijomis (ir įdėtų funkcijų apibrėžtimis), o tada ieškoti pasaulinių. Tai yra.

Kitų sričių nėra. Užrašas (ir kitas junginys, if ir try ) nesukuria naujų įdėtų domenų. Tik apibrėžtys (paketai, moduliai, funkcijos, klasės ir objektų pavyzdžiai).

Klasės apibrėžimo viduje pavadinimai yra klasės vardų erdvės dalis. Pavyzdžiui, code2 turi būti kvalifikuotas su klasės pavadinimu. Paprastai Foo.code2 . Tačiau self.code2 taip pat veiks, nes „Python“ objektai žiūri į turinčią klasę kaip atsarginę.

Objektas (klasės egzempliorius) turi egzempliorinius kintamuosius. Šie pavadinimai yra objekto vardų erdvėje. Jie turi būti objekto kvalifikuoti. ( variable.instance .)

Iš klasės metodo turite vietinius ir pasaulinius kintamuosius. Jūs sakote „ self.variable kad pasirinktumėte egzempliorių kaip vardų self.variable . Jūs pastebėsite, kad self yra argumentas kiekvienai klasės nario funkcijai, todėl ji yra vietinės vardų erdvės dalis.

Žr. „ Python“ taikymo srities taisykles , „ Python“ taikymo sritį, kintamą taikymo sritį.

11
15 нояб. Atsakymą pateikė S.Lott lapkričio 15 d. 2008-11-15 05:03 '08, 5:03 2008-11-15 05:03

Kur yra x?

x nerastas, nes nenustatėte jo. :-) Tai galima rasti kode1 (global) arba kodu3 (vietiniu), jei jį paskelbiate.

code2 (klasės nariai) nemato, kad koduotų tos pačios klasės metodus - dažniausiai tuos asmenis vadinate savimi. code4 / code5 (kilpos) gyvena tame pačiame rajone kaip ir kodas3, taigi, jei parašėte x šioje vietoje, pakeisite kodą3 apibrėžtą x egzempliorių, nesukuriant naujo x.

„Python“ yra statiškai susietas, todėl, jei perduodate šlamštą į kitą funkciją, šlamštas vis tiek turės prieigą prie pasaulinių kintamųjų modulyje, iš kurio jis buvo pateiktas (apibrėžtas kodu1), ir visose kitose srityse (žr. Toliau). Kodo2 nariai vėl bus prieinami per save.

lambda nesiskiria nuo def. Jei funkcijoje yra naudojamas lambda, jis yra toks pat, kaip ir įdėtos funkcijos apibrėžimas. Python 2.2 ir vėlesnėse versijose yra įdėtos vietos. Tokiu atveju galite susieti x bet kuriuo lizdų lygiu, o „Python“ pasirinks pačią aukščiausią instanciją:

 x= 0 def fun1(): x= 1 def fun2(): x= 2 def fun3(): return x return fun3() return fun2() print fun1(), x 2 0 

fun3 mato x atvejį iš artimiausios srities, kuri yra funkcija, susijusi su fun2. Tačiau kiti „x“ atvejai, apibrėžti „fun1“ ir visame pasaulyje, neturi įtakos.

Prieš „nested_scopes“, „Python pre-2.1“ ir 2.1 punktuose, jei konkrečiai neprašysite šios funkcijos, naudodamiesi „ateities“ importo sritimis - fun1 ir fun2, fun3 nėra matomas, todėl „S.Lott“ atsakymas laikomas ir jūs gaunate visuotinį x:

 0 0 
7
15 нояб. atsakymas pateikiamas lapkričio 15 d. 2008-11-15 15:44 '08 15:44 2008-11-15 15:44

Kiti klausimai apie žymi dinamines kalbas arba Užduoti klausimą