Ką daryti, jei __name__ == "__main__": ar?

Ką daryti, if __name__ == "__main__": :?

 # Threading example import time, thread def myfunction(string, sleeptime, lock, *args): while True: lock.acquire() time.sleep(sleeptime) lock.release() time.sleep(sleeptime) if __name__ == "__main__": lock = thread.allocate_lock() thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock)) thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock)) 
4672
07 янв. Skirta sausio 7 d 2009-01-07 07:11 '09, 07:11 AM 2009-01-07 07:11
ответ 31 atsakymų
  • 1
  • 2

Kai „Python“ vertėjas skaito šaltinio failą, jis atlieka du dalykus:

  • ji nustato keletą specialių kintamųjų, pvz., __name__ , ir tada

  • jis atlieka visą faile rastą kodą.

Pažiūrėkime, kaip jis veikia ir kaip jis susijęs su jūsų klausimu apie __name__ patikrinimus, kuriuos visada matome Python scenarijuose.

Kodo pavyzdys

Naudokime šiek tiek kitokį pavyzdinį kodą, kad sužinotume, kaip veikia importas ir scenarijai. Tarkime, kad toliau yra faile, pavadintame foo.py

 # Suppose this is foo.py. print("before import") import math print("before functionA") def functionA(): print("Function A") print("before functionB") def functionB(): print("Function B {}".format(math.sqrt(100))) print("before __name__ guard") if __name__ == '__main__': functionA() functionB() print("after __name__ guard") 

Specialūs kintamieji

Kai „Python“ vertėjas skaito šaltinio failą, jis pirmiausia apibrėžia keletą specialių kintamųjų. Šiuo atveju mes pasirūpinsime kintamuoju __name__ .

Kai jūsų modulis yra pagrindinė programa

Jei naudojate savo modulį (šaltinio failą) kaip pagrindinę programą, pvz.,

 python foo.py 

vertėjas priskirs "__main__" eilutės __name__ kintamajam __name__ , t.y.

 # It as if the interpreter inserts this at the top # of your module when run as the main program. __name__ = "__main__" 

Kai modulį importuoja kitas

Kita vertus, tarkime, kad kitas modulis yra pagrindinė programa ir importuoja jūsų modulį. Tai reiškia, kad pagrindinėje programoje arba kitame modulyje pagrindinė programa importuoja tokį operatorių:

 # Suppose this is in some other main program. import foo 

Tokiu atveju vertėjas žiūri į jūsų modulio failo pavadinimą, foo.py , foo.py .py ir priskirkite šią eilutę į savo modulio kintamąjį __name__ , t.y.

 # It as if the interpreter inserts this at the top # of your module when it imported from another module. __name__ = "foo" 

Modulio kodo vykdymas

Nustatę specialius kintamuosius, vertėjas atlieka visą modulyje esantį kodą, vieną išraišką vienu metu. Jūs galite atidaryti kitą >

Visada

Pirmiausia ji spausdina eilutę "before import" (be kabučių).

Antra, ji įkelia math modulį ir priskiria jį kintamajam pavadinimu math . Tai prilygsta import math pakeitimui taip (atkreipkite dėmesį, kad __import__ yra Python žemo lygio funkcija, kuri priima eilutę ir pradeda faktinį importą):

 # Find and load a module given its string name, "math", # then assign it to a local variable called math. math = __import__("math") 

Trečia, ji spausdina eilutę "before functionA" .

Ketvirta, ji vykdo def bloką, sukuria funkcinį objektą ir paskui priskiria šį funkcinį objektą kintamajam, pavadintam functionA .

Penkta, ji spausdina eilutę "before functionB" .

Šešta, ji atlieka antrąjį bloką def , sukurdama kitą funkcijų objektą, ir paskui ją priskiria kintamajam, pavadintam functionB .

Septinta, ji išspausdina eilutę "before __name__ guard" .

Tik tada, kai jūsų modulis yra pagrindinė programa.

Aštunta, jei jūsų modulis yra pagrindinė programa, jis pamatys, kad __name__ tiesų __name__ nustatytas į "__main__" ir jis "__main__" dvi funkcijas, "__main__" eilutes "Function A" ir "Function B 10.0" .

Tik tada, kai jūsų modulį importuoja kitas.

Aštuntas (vietoj), jei jūsų modulis nėra pagrindinė programa, bet kitas buvo importuotas, tada __name__ bus "foo" o ne "__main__" , ir "__main__" iš „ if .

Visada

Devinta, abiejose situacijose bus atspausdinta eilutė "after __name__ guard" .

Santrauka

Galiausiai tai bus spausdinama dviem atvejais:

 # What gets printed if foo is imported as a regular module before import before functionA before functionB before __name__ guard after __name__ guard 

Kodėl tai veikia?

Jūs, žinoma, gali stebėtis, kodėl kažkas to nori. Na, kartais norite parašyti .py failą, kuris gali būti naudojamas kitoms programoms ir moduliams kaip modulis ir gali būti paleistas kaip pagrindinė programa. Pavyzdžiai:

  • Jūsų modulis yra biblioteka, tačiau norite turėti scenarijų režimą, kuriame jis atlieka kai kuriuos vieneto testus ar demonstracijas.

  • Jūsų modulis naudojamas tik kaip pagrindinė programa, tačiau jis turi kelis vieneto testus, o bandymų aplinka veikia importuodama .py failus, pvz., Scenarijų, ir vykdydama specialias testavimo funkcijas. Nenorite, kad jis bandytų paleisti scenarijų tik todėl, kad jis importuoja modulį.

  • Jūsų modulis dažniausiai naudojamas kaip pagrindinė programa, bet taip pat suteikia patogią programuotojo API pažangiems vartotojams.

Be šių pavyzdžių, yra elegantiška, kad scenarijaus naudojimas „Python“ paprasčiausiai nustato keletą magiškų kintamųjų ir importuoja scenarijų. Skripto vykdymas yra šalutinis scenarijaus modulio importavimo efektas.

Maistas mąstymui

  • Klausimas: Ar galiu turėti keletą tikrintuvo blokų __name__ ? Atsakymas: tai keista, bet kalba jums nesustabdys.

  • Tarkime, kad foo2.py Kas atsitiks, jei komandinėje eilutėje sakote „ python foo2.py “? Kodėl?

 # Suppose this is foo3.py. def functionA(): print("a1") from foo3 import functionB print("a2") functionB() print("a3") def functionB(): print("b") print("t1") print("m1") functionA() print("m2") print("t2") 
  • Ką jis darys, kai naudojamas kaip scenarijus? Kada importuojama kaip modulis?
5003
07 янв. atsakymas buvo pateiktas p. Fooz 07 Jan 2009-01-07 07:26 '09, 07:26 AM 2009-01-07 07:26

Kai paleisite scenarijų, jį perduosite kaip komandą Python vertėjui,

 python myscript.py 

įvykdomas visas kodas, kuris yra 0 lygyje. Tam tikros funkcijos ir klasės yra apibrėžtos, bet neapibrėžtos, bet nė vienas jų kodas nepradedamas. Skirtingai nuo kitų kalbų, nėra main() funkcijos, kuri automatiškai pradėtų veikti - main() funkcija netiesiogiai turi visą kodą viršutiniame lygmenyje.

Tokiu atveju aukščiausio lygio kodas yra if blokas. __name__ yra integruotas kintamasis, įvertinantis dabartinio modulio pavadinimą. Tačiau, jei modulis paleidžiamas tiesiogiai (kaip ir myscript.py aukščiau), vietoj __name__ nustatoma eilutė "__main__" . Tokiu būdu, galite patikrinti, ar jūsų scenarijus yra vykdomas tiesiogiai ar importuojant ką nors kito, bandydami

 if __name__ == "__main__": ... 

Jei jūsų scenarijus importuojamas į kitą modulį, bus importuojamos jo įvairios funkcijos ir klasės apibrėžimai, o jo aukščiausio lygio kodas bus įvykdytas, tačiau to paties bandymo kodas, if aukščiau, laimėjo, nes ši sąlyga neįvykdyta. Kaip pagrindinį pavyzdį apsvarstykite šiuos du scenarijus:

 # file one.py def func(): print("func() in one.py") print("top-level in one.py") if __name__ == "__main__": print("one.py is being run directly") else: print("one.py is being imported into another module") 
 # file two.py import one print("top-level in two.py") one.func() if __name__ == "__main__": print("two.py is being run directly") else: print("two.py is being imported into another module") 

Dabar, jei skambinate vertėjui kaip

 python one.py 

Išėjimas bus

 top-level in one.py one.py is being run directly 

Jei paleisite two.py :

 python two.py 

Jūs gaunate

 top-level in one.py one.py is being imported into another module top-level in two.py func() in one.py two.py is being run directly 

Taigi, kai įkeliamas one modulis, jo __name__ yra "one" vietoj "__main__" .

1577 m
07 янв. atsakymą pateikė Adam Rosenfield 07 jan. 2009-01-07 07:28 '09, 7:28, 2009-01-07 07:28

Paprasčiausias __name__ ( __name__ ) kintamojo paaiškinimas yra toks:

Sukurkite šiuos failus.

 # a.py import b 

ir taip pat

 # b.py print "Hello World from %s!" % __name__ if __name__ == '__main__': print "Hello World again from %s!" % __name__ 

Vykdydami juos, daroma tokia išvada:

 $ python a.py Hello World from b! 

Kaip matote, kai importuojamas modulis, „Python globals()['__name__'] šiame modulyje nustato modulio pavadinimą globals()['__name__'] . Be to, kai importuojate visus modulio kodus. Kadangi if vertinamas kaip False ši dalis nevykdoma.

 $ python b.py Hello World from __main__! Hello World again from __main__! 

Kaip matote, kai failas vykdomas, „Python globals()['__name__'] šiame faile įdiegia „ globals()['__name__'] į "__main__" . Šį kartą, if vertinamas kaip True ir vykdomas.

615
atsakymas pateikiamas pi. 07 Sau 2009-01-07 14:35 '09 ne 14:35 2009-01-07 14:35

Ką daryti, if __name__ == "__main__": :?

Aprašyti pagrindus:

  • Bendras kintamasis __name__ modulyje, kuris yra jūsų programos įvedimo taškas, yra '__main__' . Priešingu atveju tai yra pavadinimas, į kurį importuojate modulį.

  • Taigi, kodas, if blokas bus, bus paleistas tik tada, kai modulis yra jūsų programos įvedimo taškas.

  • Jis leidžia importuoti kodą modulyje kitiems moduliams, nevykdant importuojamo kodo.


Kodėl mums tai reikia?

Kodo kūrimas ir testavimas

Tarkime, kad rašote Python scenarijų, skirtą naudoti kaip modulį:

 def do_important(): """This function does something very important""" 

Modulį galite išbandyti pridėdami šią funkciją į apačią:

 do_important() 

ir paleiskite jį (komandų eilutėje) kažką panašaus:

 ~$ python important.py 

Problema

Tačiau, jei norite importuoti modulį į kitą scenarijų:

 import important 

Importas vadins do_important funkciją, todėl tikriausiai komentuosite savo skambutį į do_important() funkciją.

 # do_important() # I must remember to uncomment to execute this! 

Ir tada jums reikės prisiminti, jei komentavote į bandymo funkciją. Ir šis papildomas sudėtingumas reiškia, kad jūs tikriausiai pamiršsite, kas dar labiau apsunkins jūsų kūrimo procesą.

Geriausias būdas

Kintamasis __name__ reiškia vardų sritį, kur šiuo metu yra „Python“ vertėjas.

Importuotame modulyje yra šio modulio pavadinimas.

Tačiau pirminiame modulyje (arba „Python“ interaktyvioje sesijoje, t. Y. „Skaityti interpretatorių,„ Eval “,„ Print loop “arba REPL interpretatorius) viskas pradedama nuo "__main__" .

Taigi, jei prieš atlikdami patikrinimą:

 if __name__ == "__main__": do_important() 

Naudojant aukščiau pateiktą informaciją, jūsų kodas bus vykdomas tik tada, jei jį naudosite kaip pagrindinį modulį (arba tyčia jį pavadinsite iš kito scenarijaus).

Dar geriau

Yra Python būdas jį patobulinti.

Ką daryti, jei norime paleisti šį verslo procesą ne iš modulio?

Jei įvesime kodą, kurį norime įgyvendinti, kai kuriame ir išbandome tokią funkciją, mes patikriname '__main__' iškart po:

 def main(): """business logic for when running this module as the primary one!""" setup() foo = do_important() bar = do_even_more_important(foo) for baz in bar: do_super_important(baz) teardown() # Here our payoff idiom! if __name__ == '__main__': main() 

Dabar mes turime galutinę funkciją mūsų modulio pabaigoje, kuri veiks, jei modulį atliksime kaip pagrindinį modulį.

Tai leis moduliui ir jo funkcijoms bei klasėms importuoti į kitus scenarijus nepradedant main funkcijos, taip pat leidžia jums skambinti moduliu (ir jo funkcijomis ir klasėmis) dirbant iš kito '__main__' , t.y.

 import important important.main() 

Šį idiomą taip pat galima rasti Python dokumentuose __main__ modulio paaiškinime. Šiame tekste nurodoma:

Šis modulis reiškia (kitaip anoniminį) sritį, kurioje pagrindinė vertėjo programa yra komandų, skaitomų arba iš standartinės įvesties, iš scenarijaus failo, arba interaktyvios eilutės. Tai aplinka, kurioje idiomatinis „sąlyginis scenarijus“ sukelia scenarijų:

 if __name__ == '__main__': main() 
451
23 нояб. atsakymą pateikė Aaron Hall lapkričio 23 d. 2013-11-23 07:38 '13, 7:38 am 2013-11-23 07:38

if __name__ == "__main__" yra dalis, kuri vykdoma, kai scenarijus pradedamas nuo (pvz.) komandinės eilutės, naudojant komandą kaip python myscript.py .

100
07 янв. Harley Holcombe atsakymas 07 Jan 2009-01-07 07:14 '09, 7:14 val. 2009-01-07 07:14

Ką daryti, if __name__ == "__main__": :?

__name__ yra pasaulinis kintamasis („Python“, „global __name__ reiškia modulio lygio lygmenyje ), kuris egzistuoja visose vardų erdvėse. Paprastai tai yra modulio pavadinimas (pvz., str tipas).

Tačiau kaip vienintelis ypatingas atvejis, kai vykdomas bet kuris veikiantis „Python“ procesas, kaip ir „mycode.py“:

 python mycode.py 

kitaip anoniminė pasaulinė vardų sritis priskiriama reikšmei '__main__' __name__ .

Taigi, įskaitant galutines eilutes

 if __name__ == '__main__': main() 
  • „mycode.py“ scenarijaus pabaigoje,
  • kai tai yra pagrindinis pradinio taško modulis, kuris pradedamas pythono procesu,

bus atliktas unikalus funkcijos main scenarijus.

Kitas šio konstrukcijos naudojimo privalumas: taip pat galite importuoti kodą kaip modulį į kitą scenarijų ir tada paleisti pagrindinę funkciją, jei ir kada jūsų programa nusprendžia:

 import mycode # ... any amount of other code mycode.main() 
66
14 окт. atsakymą pateikė Aaron Hall spalio 14 d. 2014-10-14 23:22 '14, 23:22, 2014-10-14 23:22

Yra daug skirtingų svarstymų dėl nagrinėjamo kodo mechanikos: „Kaip“, bet man tai nebuvo prasminga, kol nesupratau „Kodėl“. Tai turėtų būti ypač naudinga naujiems programuotojams.

Pasirinkite failą „ab.py“:

 def a(): print('A function in ab file'); a() 

Ir antrasis failas „xy.py“:

 import ab def main(): print('main function: this is where the action is') def x(): print ('peripheral task: might be useful in other projects') x() if __name__ == "__main__": main() 

Ką šis kodas iš tikrųjų daro?

Kai vykdote xy.py , import ab . Importo pareiškimas pradeda modulį iš karto po importavimo, todėl ab operacijos atliekamos iki likusio xy . Baigęs ab , jis tęs su xy .

Vertėjas seka, kurie scenarijai veikia su __name__ . Kai paleisite scenarijų - nesvarbu, ką tai vadinate, vertėjas vadina jį "__main__" , todėl jis tampa pagrindiniu arba „namų“ scenarijumi, kuris grąžinamas paleisdamas išorinį scenarijų.

Bet kuris kitas scenarijus, vadinamas "__main__" iš šio scenarijaus, priskiria jo failo pavadinimą kaip __name__ (pvz., __name__ == "ab.py" ). Todėl eilutė, if __name__ == "__main__": yra testo vertėjas, kad nustatytų, ar jis interpretuoja / apdoroja pradinį scenarijų, kuris buvo iš pradžių įvykdytas, arba jei jis laikinai ieško kito (išorinio) scenarijaus. Tai suteikia programuotojui lankstumo, kad scenarijus elgtųsi skirtingai, jei jis buvo įvykdytas tiesiogiai arba buvo iškviestas iš išorės.

Leiskite man eiti per pirmiau minėtą kodą, kad suprastume, kas vyksta, pirmiausia sutelkiant dėmesį į nepastebėtas linijas ir tvarką, kurią jie vaizduoja scenarijuose. Atminkite, kad funkcijos - arba blokai - savaime nieko nedaro, kol jie nebus vadinami. Ką vertėjas gali pasakyti, jei jis pasmerkė save:

  • Atidarykite „xy.py“ failą kaip „namų“ failą; Pavadinimas "__main__" __name__ kintamajame.
  • Importuokite ir atidarykite failą su __name__ == "ab.py" .
  • O, funkcija. Aš tai prisimenu.
  • Na, a() ; Aš ką tik sužinojau apie tai. Spausdinti "Funkcija ab faile".
  • Failo pabaiga; atgal į "__main__" !
  • O, funkcija. Aš tai prisimenu.
  • Dar vienas.
  • Funkcija x() ; ok, spausdinimas „periferinė užduotis: gali būti naudingas kituose projektuose“.
  • Kas tai? if Na, ši sąlyga įvykdyta ( __name__ kintamasis nustatomas į "__main__" ), todėl "__main__" main() funkciją ir spausdinu "pagrindinę funkciją: tai yra veiksmas."

Apatinės dvi eilutės reiškia: "Jei tai yra scenarijus "__main__" arba" home ", vykdykite pagrindinę funkciją main() . Štai kodėl pamatysite def main(): blokuoti viršų, kuriame yra pagrindinis scenarijų funkcijų srautas.

Kodėl jį įgyvendinti?

Prisiminkite, ką anksčiau pasakiau apie importo programas? Importuojant modulį, jis ne tik „atpažįsta“ jį ir laukia tolesnių nurodymų - jis iš tikrųjų atlieka visas scenarijaus operacijas. Taigi, pridėjus savo scenarijaus mėsą į main() funkciją, jis veiksmingai įdedamas į karantiną, išskiriant jį taip, kad jis nebūtų iškart pradėtas, kai importuojamas naudojant kitą scenarijų.

Vėlgi, bus išimčių, tačiau įprasta praktika yra ta, kad main() nėra vadinamas išoriniu būdu. Todėl galbūt jus domina dar vienas dalykas: jei nešaukiame main() , kodėl mes netgi vadiname scenarijų? Taip yra todėl, kad daugelis žmonių kuria savo scenarijus su autonominėmis funkcijomis, kurios sukurtos veikti nepriklausomai nuo likusio failo kodo. Vėliau jie skambinami kitur scenarijaus tekste. Tai atvedė mane į tai:

Bet kodas veikia be jo.

Taip, tai teisinga. Šios atskiros funkcijos gali būti iškviestos iš integruoto scenarijaus, kuris nėra main() funkcijoje. Jei esate įpratę (kaip ir aš, ankstyvosiose programavimo stadijose) kurdami įdėtus scenarijus, kurie daro būtent tai, ko jums reikia, ir bandysite jį vėl išsiaiškinti, jei jums reikia šios operacijos. gerai, jūs nesate pripratę prie tokios vidinės kodo struktūros, nes sunkiau kurti, ir tai nėra taip paprasta intuityvi.

Tačiau tai yra scenarijus, kuris, tikriausiai, negalėjo pavadinti savo funkcijomis, nes jei jis tai padarytų, jis nedelsdamas pradėtų skaičiuoti ir priskirti kintamuosius. Ir, greičiausiai, jei bandysite pakartotinai naudoti šią funkciją, naujasis scenarijus yra glaudžiai susijęs su senuoju, kad bus prieštaringų kintamųjų.

Dalindamiesi nepriklausomomis funkcijomis, jūs galėsite pakartotinai naudoti ankstesnį darbą skambindami juos kitu scenariju. Pavyzdžiui, pavyzdys.py gali importuoti xy.py ir skambinti x() naudojant x funkciją iš xy.py. (Galbūt ji lygina trečiąjį tam tikros teksto eilutės žodį, sukuria NumPy masyvą iš numerių sąrašo ir kvadrato juos arba iššifruoja trimatį paviršių. Galimybės yra neribotos).

(Be to, šiame klausime pateikiamas atsakymas iš @kindall, kuris galiausiai padėjo suprasti, kodėl, o ne kaip. Deja, tai buvo pažymėta kaip šio dublikato, kurį, mano nuomone, klaida).

58
29 сент. atsakymas, kurį pateikė joechoj Sep 29 2016-09-29 07:33 '16 at 7:33 2016-09-29 07:33

Kai mūsų modulyje ( M.py ) yra tam tikrų teiginių, mes norime vykdyti M.py kai jis bus paleistas kaip pagrindinis (neimportuotas), mes galime įdėti šiuos pareiškimus (bandymų pavyzdžius, spausdinimo ataskaitas) į šį, if blokuoti.

Pagal nutylėjimą (kai modulis veikia kaip pagrindinis, o ne importuotas), __name__ kintamasis yra nustatytas į "__main__" , o importuojant __name__ kintamasis gaus kitokią vertę, greičiausiai modulio pavadinimą ( 'M' ). Tai naudinga dalinant skirtingus modulių variantus ir atskiriant jų konkrečias įvesties ir išvesties instrukcijas, taip pat esant bandymų atvejams.

Trumpai tariant , naudokite šį " if __name__ == "main" blokas, kad (tam tikras) kodas nebūtų pradėtas, kai modulis importuojamas.

44
03 апр. Atsakymą pateikė Nabeel Ahmed 03 Bal. 2013-04-03 17:09 '13, 17:09, 2013-04-03 17:09

Pažvelkime atsakymą abstrakčiau:

Tarkime, kad šis kodas yra x.py:

 ... <Block A> if __name__ == '__main__': <Block B> ... 

Blokai A ir B pradedami paleisdami x.py.

Bet tik pradėjus kitą modulį, pradedamas tik blokas A (o ne B), pvz., „Y.py“, kuriame xy importuojamas, ir kodas iš jo pradedamas (pavyzdžiui, kai „x“ funkcija „Py“ yra vadinama iš y.py) .

35
20 янв. atsakymas Alisa sausio 20 d 2015-01-20 20:48 '15 ne 20:48 2015-01-20 20:48

Paprasčiau tariant, __name__ yra kintamasis, apibrėžtas kiekvienam scenarijui, kuris nustato, ar scenarijus veikia kaip pagrindinis modulis, ar veikia kaip importuotas modulis.