[python] 🚀 __Name__ == “__main__”: ne yapar?
Ne yapar if __name__ == "__main__": ?
Python yorumlayıcısı bir kaynak dosyayı okuduğunda, iki şey yapar:
__name__ ve gibi birkaç özel değişken ayarlar
dosyada bulunan tüm kodu çalıştırır.
Bunun nasıl çalıştığını ve __name__ Python komut dosyalarında her zaman gördüğümüz çeklerle ilgili sorunuzla nasıl ilgili olduğunu görelim.
İçe aktarma ve komut dosyalarının nasıl çalıştığını keşfetmek için biraz farklı bir kod örneği kullanalım. Aşağıdakilerin adında bir dosyada olduğunu varsayalım foo.py .
Python yorumlayıcısı bir kaynak dosyayı okuduğunda, önce birkaç özel değişken tanımlar. Bu durumda, __name__ değişkeni önemsiyoruz .
Modülünüz Ana Program Olduğunda
Ana program olarak modülünüzü (kaynak dosya) çalıştırıyorsanız, örneğin
tercüman kodlanmış dize atar "__main__" için __name__ değişken, yani
Modülünüz Başka Birinden İçe Aktarıldığında
Öte yandan, başka bir modülün ana program olduğunu ve modülünüzü içe aktardığını varsayalım. Bu, ana programda veya başka bir modülde ana programın ithalatında böyle bir ifade olduğu anlamına gelir:
Bu durumda, tercüman modülünüzün dosya adına bakacak foo.py , sıyrılacak .py ve bu dizgiyi modülünüzün __name__ değişkenine atayacaktır.
Modül Kodunu Çalıştırma
Özel değişkenler ayarlandıktan sonra, tercüman modüldeki tüm kodu, her seferinde bir ifade olarak yürütür. Kod açıklamasıyla birlikte başka bir pencereyi açmak isteyebilirsiniz, böylece bu açıklamayı takip edebilirsiniz.
Dizeyi yazdırır "before import" (tırnak işaretleri olmadan).
math Modülü yükler ve denilen bir değişkene atar math . Bu, import math aşağıdakilerle değiştirmeye eşdeğerdir ( __import__ Python'da bir dize alan ve gerçek içe aktarmayı tetikleyen düşük düzeyli bir işlevdir):
Dizeyi yazdırır "before functionA" .
def Bir fonksiyon nesnesi yaratarak, daha sonra bu fonksiyon nesnesini adı verilen bir değişkene atayarak bloğu çalıştırır functionA .
Dizeyi yazdırır "before functionB" .
İkinci def bloğu çalıştırır, başka bir fonksiyon nesnesi yaratır, sonra onu bir değişkene atar functionB .
Dizeyi yazdırır "before __name__ guard" .
Sadece Modülünüz Ana Program Olduğunda
Modülünüz ana programsa, o zaman __name__ gerçekten ayarlandığını görecek "__main__" ve iki işlevi çağıracak, dizgileri "Function A" ve "Function B 10.0" .
Yalnızca Modülünüz Başka Birinden İçe Aktarıldığında
( Yerine sizin modül ana program değil ama başka biri tarafından ithal ise), sonra __name__ olacak "foo" değil "__main__" ve gövdesini atlarsınız if açıklamada.
Her "after __name__ guard" iki durumda da dizeyi basacaktır .
Özet olarak, işte iki durumda ne basılacak:
Neden birisinin bunu istediğini merak ediyor olabilirsin. Bazen .py , diğer programlar ve / veya modüller tarafından modül olarak kullanılabilecek ve aynı zamanda ana programın kendisi olarak da çalıştırılabilen bir dosya yazmak istersiniz . Örnekler:
Modülünüz bir kütüphanedir, ancak bazı ünite testleri veya bir demo çalıştığı bir script moduna sahip olmak istersiniz.
Modülünüz yalnızca ana program olarak kullanılır, ancak bazı testlere sahiptir ve test çerçevesi .py betiğiniz gibi dosyaları içe aktararak ve özel test fonksiyonları çalıştırarak çalışır. Senaryoyu çalıştırmayı denemesini istemezsin çünkü sadece modülü içe aktarıyor.
Modülünüz çoğunlukla ana program olarak kullanılır, ancak aynı zamanda ileri düzey kullanıcılar için programcı dostu bir API sağlar.
Bu örneklerin ötesinde, Python'da bir komut dosyası çalıştırmanın sadece birkaç sihirli değişken ayarlaması ve senaryoyu içe aktarması zarif. Komut dosyasını "Çalıştırmak", komut dosyasının modülünü içe aktarmanın bir yan etkisidir.
Soru: Birden fazla __name__ kontrol bloğunu alabilir miyim ? Cevap: Bunu yapmak çok garip, ancak dil sizi durdurmuyor.
Aşağıdakilerin içinde olduğunu varsayalım foo2.py . python foo2.py Komut satırında söylerseniz ne olur ? Niye ya?
Şimdi, __name__ check-in işlemini kaldırırsanız ne olacağını anlayın foo3.py :
Bir komut dosyası olarak kullanıldığında bu ne işe yarayacak? Modül olarak ne zaman alınır?
Mr Fooz2009-01-072009-01-07 04:26:43Z
Komut dosyanız Python yorumlayıcısına komut olarak geçirilerek çalıştırıldığında,
Girinti seviyesi 0 olan tüm kodlar çalıştırılır. Tanımlanan fonksiyonlar ve sınıflar tanımlanmıştır, ama tanımlanmış fakat kodlarından hiçbiri çalıştırılmaz. Diğer dillerden farklı olarak, main() otomatik olarak çalışan bir işlev yoktur - main() işlev dolaylı olarak tüm kodları en üst düzeydedir.
Bu durumda, üst seviye kod bir if bloktur. __name__ mevcut modülün ismini değerlendiren dahili bir değişkendir. Bununla birlikte, bir modül doğrudan çalıştırılıyorsa ( myscript.py yukarıdaki gibi), __name__ bunun yerine dizeye ayarlanır "__main__" . Böylece, komut dosyanızın doğrudan çalıştırılıp çalıştırılmadığını veya test ederek başka bir şey tarafından içe aktarıldığını test edebilirsiniz.
Komut dosyanız başka bir modüle içe aktarılıyorsa, çeşitli işlevi ve sınıf tanımları içe aktarılacak ve üst düzey kodu çalıştırılacak, ancak if yukarıdaki fıkranın o zamanki gövdesindeki kod koşulu olduğu gibi çalıştırılmayacak tanışmadım. Temel bir örnek olarak, aşağıdaki iki komut dosyasını göz önünde bulundurun:
Şimdi, tercümanı çağırdıysanız,
Eğer two.py koşarsanız:
Böylece, modül one yüklendiğinde, bunun yerine __name__ eşittir . "one" "__main__"
Adam Rosenfield2009-01-072009-01-07 04:28:23Z
__name__ Değişken (imho) için en basit açıklama şudur:
Onları çalıştırmak size şu çıktıları verecektir:
Gördüğünüz gibi, bir modül içe aktarıldığında, Python globals()['__name__'] bu modülde modülün adına ayarlanır . Ayrıca, içeri aktardıktan sonra modüldeki tüm kodlar çalıştırılmaktadır. As if için deyim değerlendirir False bu bölümünde yürütülmez.
Gördüğünüz gibi, bir dosya yürütüldüğünde Python globals()['__name__'] bu dosyayı olarak ayarlar "__main__" . Bu sefer, if ifade değerlendirir True ve çalıştırılmaktadır.
Temel bilgileri ana hatlarıyla belirtmek için:
Genel değişken, __name__ programınıza giriş noktası olan modülde '__main__' . Aksi takdirde, bu modül tarafından aldığınız addır.
Bu nedenle, if bloğun altındaki kod yalnızca modül programınıza giriş noktasıysa çalışır.
Modüldeki kodun içe aktarılmakta olan kod bloğunu çalıştırmadan diğer modüller tarafından alınabilmesini sağlar.
Modül olarak kullanılmak üzere tasarlanmış bir Python betiği yazdığınızı varsayalım:
Bu işlev çağrısı, aşağıya ekleyerek modülü test edebilirsiniz :
ve (komut isteminde) aşağıdaki gibi bir şeyle çalıştırma:
Ancak, modülü başka bir betiğe almak istiyorsanız:
İçe aktarırken, do_important işlev çağrılır, bu nedenle işlev çağrınızı muhtemelen do_important() en altta yorumlarsınız.
Ardından, test işlevi çağrınızı yorumlayıp yorumlamadığınızı hatırlamanız gerekir. Ve bu ekstra karmaşıklık, gelişim sürecinizi daha zahmetli hale getirerek, unutmanızın muhtemel olduğu anlamına gelir.
__name__ Python yorumlayıcısı anda olur her yerde ad alanına değişken işaret eder.
Alınan bir modülün içinde, o modülün adı.
Ancak birincil modülün içinde (veya etkileşimli bir Python oturumu, yani tercümanın Oku, Değerlendir, Baskı Döngüsü veya REPL) içinde her şeyi çalıştırıyorsunuz "__main__" .
Yani çalıştırmadan önce kontrol ederseniz:
Yukarıdakilerle, kodunuz yalnızca birincil modül olarak çalıştırdığınızda yürütülür (veya kasıtlı olarak başka bir komut dosyasından çağırır).
Daha da iyi bir yol
Bununla birlikte, bunu geliştirmek için Pythonic bir yol var.
Ya bu iş sürecini modül dışından yürütmek istiyorsak?
Eğer kodu koyarsak, böyle bir fonksiyonda geliştikçe ve test ederken egzersiz yapmak istiyoruz ve '__main__' hemen ardından kontrollerimizi yapmak istiyoruz :
Şimdi, modülü birincil modül olarak çalıştırırsak çalışacak olan modülümüzün sonu için son bir işleve sahibiz.
Modül ve fonksiyonlarının ve sınıflarının, main fonksiyonu çalıştırmadan diğer komut dosyalarına alınmasına izin verecek ve ayrıca farklı bir '__main__' modülden çalıştırırken modülün (ve fonksiyonlarının ve sınıflarının) çağrılmasına izin verecektir.
Bu deyim, Python belgelerinde ayrıca __main__ modülün açıklamasında bulunabilir . Bu metin şöyle diyor:
Bu modül, tercümanın ana programının yürütüldüğü (aksi halde isimsiz) kapsamı temsil eder - komutlar standart girdiden, bir komut dosyasından veya etkileşimli bir komuttan okunur. Bu deyimsel “koşullu script” stanza'nın betik çalışmasına neden olduğu ortamdır:
Aaron Hall2013-11-232013-11-23 04:38:25Z
if __name__ == "__main__" komut dosyası, bir komut kullanarak komut satırından (say) çalıştırıldığında çalışan kısımdır python myscript.py .
Harley Holcombe2009-01-072009-01-07 04:14:23Z
__name__ tüm isim alanlarında bulunan global bir değişken (Python'da global aslında modül düzeyinde demektir ). Tipik olarak modülün adıdır (bir str tür olarak).
Ancak, tek özel durum olarak, hangi kodda Python işleminde çalışırsanız çalışın, mycode.py:
Aksi anonim genel ad değeri atanır '__main__' onun için __name__ .
Böylece, son satırlar dahilhttps://docs.python.org/library/__main__.html
mycode.py betiğinizin sonunda,
Python işlemi tarafından çalıştırılan birincil, giriş noktası modülü olduğunda,
Komut dosyanızın benzersiz tanımlanmış main işlevinin çalışmasına neden olur .
Bu yapıyı kullanmanın bir başka yararı da: kodunuzu başka bir komut dosyasında bir modül olarak içe aktarabilir ve ardından programınız karar verirse ana işlevi çalıştırabilirsiniz:
Aaron Hall2014-10-142014-10-14 20:22:55Z
Burada, söz konusu kodun mekaniği olan “Nasıl” dır, ancak “Neden” i anlamadan hiçbiri anlam ifade etmedi. Bu, özellikle yeni programcılar için faydalı olmalıdır.
"Ab.py" dosyasını alın:
İdam ettiğinde xy.py , sen import ab . İmport ifadesi, modülü derhal içe aktarma sırasında çalıştırır, bu nedenle ab işlemler geri kalanının önünde gerçekleştirilir xy . Bir kez bittiğinde ab devam eder xy .
Tercüman hangi komut dosyalarının çalıştığını takip eder __name__ . Bir betiği çalıştırdığınızda - neye ad verdiğiniz önemli değil - tercüman onu çağırır "__main__" , harici bir betiği çalıştırdıktan sonra döndürülen ana veya 'ev' betiğini yapar.
Bu "__main__" komut dosyasından çağrılan başka bir komut dosyasına dosya adı __name__ (örn __name__ == "ab.py" .) Olarak atanır . Bu nedenle, satır if __name__ == "__main__": , ilk olarak yürütülen 'home' komut dosyasını mı yorumlayıp ayrıştırdığını mı yoksa geçici olarak başka bir (harici) komut dosyasına mı bakacağını belirlemek için tercümanın testidir. Bu, programcıya doğrudan harici olarak çağrılırsa komut dosyasının farklı davranmasını sağlama esnekliği sağlar.
Neler olup bittiğini anlamak için ilk önce girintisiz satırlara ve betiklerde göründükleri sıraya odaklanarak yukarıdaki kodu inceleyelim. Unutma - ya da def - bloklar çağrılana kadar kendi başlarına hiçbir şey yapmazlar. Tercüman kendisine mırıldanırsa ne söyleyebilir:
Xy.py dosyasını 'home' dosyası olarak açın; diyoruz "__main__" içinde __name__ değişken.
İle dosyayı alın ve açın __name__ == "ab.py" .
Oh, bir işlev. Bunu hatırlayacağım.
Tamam, işlev a() ; Bunu daha yeni öğrendim. ' Ab dosyasında bir işlev' yazdırılıyor .
Dosyanın sonu; geri dön "__main__" !
İşlev x() ; tamam, ' çevre görevi: diğer projelerde faydalı olabilir ' yazısını yazdırın .
Bu nedir? Bir if açıklama. Eh, koşul yerine getirildi (değişken __name__ ayarlandı "__main__" ), bu yüzden main() fonksiyona gireceğim ve ' ana işlev: eylemin olduğu yer burası ' yazdıracağım .
Alttaki iki satır: "Bu "__main__" ya da 'home' betiği ise, adı verilen işlevi çalıştırın main() ". Bu yüzden def main(): , komut dosyasının işlevselliğinin ana akışını içeren bir blokaj yukarı göreceksiniz .
Bunu neden uyguladın?
İçe aktarma ifadeleri hakkında daha önce söylediklerimi hatırlıyor musunuz? Bir modülü içe aktardığınızda, sadece onu 'tanımaz' ve daha fazla talimat beklemez - aslında betiğin içindeki tüm çalıştırılabilir işlemleri çalıştırır. Böylece, betiğinizin etini main() işleve koymak, onu başka bir komut dosyası tarafından içe aktarıldığında derhal çalıştırılmaması için yalıtımlı hale getirerek karantinaya alır.
Yine, istisnalar olacaktır, ancak yaygın uygulama, main() genellikle dışarıdan aranmaz. Öyleyse bir şeyi daha merak ediyor olabilirsiniz: eğer aramıyorsak main() , neden senaryoyu çağırıyoruz? Bunun nedeni birçok kişinin komut dosyalarını, dosyadaki kodun geri kalanından bağımsız olarak çalıştırılmak üzere oluşturulan bağımsız işlevlerle yapılandırmasıdır. Daha sonra betiğin gövdesinde başka bir yere çağırılırlar. Bu beni buna getiriyor:
Ancak kod onsuz çalışır
Evet bu doğru. Bu ayrı işlevler , bir işlevin içinde bulunmayan bir satır içi komut dosyasından çağrılabilir main() . Alışmışsanız (benim gibi, programlamadaki ilk öğrenim aşamalarımda) tam olarak ihtiyacınız olanı yapan satır içi komut dosyaları oluşturmaya alıştınız ve tekrar bu işleme ihtiyacınız olursa tekrar çözmeye çalışacaksınız. kodunuz için bu tür bir iç yapıya alışık değilsiniz, çünkü inşa etmek daha karmaşık ve okumak için sezgisel değil.
Fakat bu, muhtemelen fonksiyonlarını dışarıdan çağırmaktan kaçınan bir betiktir, çünkü bunu yaparsa derhal değişkenleri hesaplamaya ve atamaya başlar. Ve bir işlevi yeniden kullanmaya çalışıyorsanız, yeni komut dosyanızın eskisiyle çelişen değişkenlerin olabileceği kadar yakından ilgilidir.
Bağımsız işlevleri ayırırken, önceki çalışmanızı başka bir komut dosyasına çağırarak yeniden kullanma becerisi kazanırsınız. Örneğin, "example.py" x() , "xy.py" den "x" işlevini kullanarak "xy.py" dosyasını alabilir ve arayabilir . (Belki belirli bir metin dizesinin üçüncü sözcüğünü büyük harf kullanmaktadır; bir sayı listesinden bir NumPy dizisi oluşturmak ve bunları kareler yapmak veya bir 3D yüzeyini azaltmak. Olasılıklar sınırsızdır.)
(Bu vesileyle, bu soruya nihayet anlamama yardımcı olduğunu @kindall kadar bir cevap içeriyor -. Neden değil how Ne yazık ki tekrarı olarak işaretlenmiş oldu bu bir ben bir hata olduğunu düşünüyorum.)
Modülümüzde ( M.py ) belli ifadeler olduğu zaman, ana olarak çalıştığında (ithal edilmediğinde) yürütülmesini istiyoruz, bu ifadeleri (test durumları, baskı cümleleri) bu if bloğun altına yerleştirebiliriz.
Varsayılan olarak (modül ana olarak çalıştığında, içe aktarılmadığında) __name__ değişken olarak ayarlanır "__main__" ve içe aktarıldığında __name__ değişken, büyük olasılıkla modülün ( 'M' ) adı olan farklı bir değer alır . Bu, modüllerin farklı değişkenlerinin bir arada çalıştırılmasında ve belirli giriş ve çıkış ifadelerinin ayrılmasında ve ayrıca test durumlarında da faydalıdır.
Kısacası , if __name__ == "main" modül içe aktarıldığında (belirli) kodun çalıştırılmasını önlemek için bu ' ' bloğunu kullanın.
Nabeel Ahmed2013-04-032013-04-03 14:09:11Z
Basitçe söylemek gerekirse __name__ , betiğin ana modül olarak mı çalıştırıldığını yoksa içe aktarılan bir modül olarak mı çalıştırıldığını tanımlayan her komut dosyası için tanımlanmış bir değişkendir.
Yani iki senaryomuz varsa;
Script1 çalıştırma çıktısı:
Ve script2'yi çalıştırmanın çıktısı:
Gördüğünüz gibi, __name__ hangi kodun 'ana' modül olduğunu söylüyor. Bu harika, çünkü sadece kod yazabilir ve C / C ++ gibi yapısal konular hakkında endişelenmenize gerek kalmaz, eğer bir dosya 'main' işlevini uygulamazsa, çalıştırılabilir olarak derlenemez ve eğer o zaman bir kütüphane olarak kullanılamaz.
Diyelim ki harika bir şey yapan bir Python betiği yazıyorsunuz ve başka amaçlar için faydalı bir kayık işlevi kullanıyorsunuz. Eğer onları kullanmak istersem, sadece betiğini alabilir ve programınızı çalıştırmadan kullanabilirim (kodunuzun sadece if __name__ == "__main__": içerik içerisinde çalıştırıldığı düşünülürse ). Oysa C / C ++ 'da, bu parçaları daha sonra dosyayı içeren ayrı bir modüle bölmek zorunda kalacaksınız. Aşağıdaki durumu hayal edin;
Oklar içe aktarma bağlantılarıdır. Her biri önceki modül kodunu eklemeye çalışan üç modül için altı dosya (dokuz, uygulama dosyalarını sayarak) ve beş bağlantı bulunur. Bu, özellikle bir kütüphane olarak derlenmedikçe, bir C projesine başka bir kod eklemeyi zorlaştırır. Şimdi Python için hayal edin:
Bir modül yazıyorsunuz ve eğer biri kodunuzu kullanmak istiyorsa, sadece içeri aktarıyorlar ve __name__ değişken programın çalıştırılabilir kısmını kitaplık bölümünden ayırmaya yardımcı oluyor.
Cevabı daha soyut bir şekilde inceleyelim:
Farz edelim ki bu kod x.py:
A ve B blokları "x.py" çalıştırdığımızda çalıştırılır.
Ancak sadece A bloğu (B değil) başka bir modül çalıştırırken çalıştırılır, örneğin "x.py", xy'nin içe aktarıldığı ve kodun oradan çalıştırıldığı ("x.py" deki bir fonksiyonun olduğu gibi) y.py den denir).
Python'u etkileşimli olarak çalıştırdığınızda, yerel __name__ değişkene bir değer atanır __main__ . Benzer şekilde, bir Python modülünü komut satırından başka bir modüle aktarmak yerine, komut satırından yürüttüğünüzde, __name__ özniteliğine modülün __main__ gerçek adı yerine bir değer atanır . Bu sayede, __name__ başka bir program için destek olarak veya komut satırından yürütülen ana uygulama olarak kendilerinin nasıl kullanıldığını belirlemek için modüller kendi değerlerine bakabilir . Bu nedenle, aşağıdaki deyim Python modüllerinde oldukça yaygındır:
__name__ Python betiğinin özniteliğinin olup olmadığını kontrol eder "__main__" . Başka bir deyişle, programın kendisi yürütülürse, öznitelik olacaktır __main__ , bu nedenle program yürütülür (bu durumda main() işlev).
Bununla birlikte, eğer Python betiğiniz bir modül tarafından kullanılıyorsa, if ifadenin dışındaki herhangi bir kod çalıştırılır, bu nedenle if \__name__ == "\__main__" sadece programın bir modül olarak kullanılıp kullanılmadığını kontrol etmek için kullanılır ve bu nedenle kodun çalıştırılıp çalıştırılmayacağına karar verir.
if __name__ == '__main__' Bununla ilgili herhangi bir şeyi açıklamadan önce , ne __name__ olduğunu ve ne yaptığını anlamak önemlidir .
Nedir __name__ ?
__name__ bir DunderAlias - küresel bir değişken olarak düşünülebilir (modüllerden erişilebilir) ve buna benzer şekilde çalışır global .
Bu gösterildiği gibi (örneğin yukarıda belirtildiği gibi genel) bir dize type(__name__) elde edildi ( <class 'str'> ), ve her ikisi için bir dahili standart Python 3 ve Python 2 alternatifler.
Sadece komut dosyalarında kullanılamaz, aynı zamanda yorumlayıcı ve modüller / paketlerde de bulunabilir.
Modül veya paket:
Bir paket veya modülde kullanıldığında __name__ dosyanın adını aldığına dikkat edin. Gerçek modülün veya paket yolunun yolu belirtilmemiş, ancak buna __file__ izin veren kendi DunderAlias'ına sahip .
__name__ Ana dosyanın (veya programın) nerede , her zaman geri döneceğini __main__ ve bir modül / paket veya başka bir Python betiğini çalıştıran herhangi bir şey olduğunda, dosyanın adını döndürdüğünü görmelisiniz. kökenli.
Değişken aracı olmak 's değeri o olabilir üzerine yazılır olmak (ortalama "gereken" yok "olabiliriz"), bir değerin üzerine yazmaktan __name__ okunabilirlik eksikliği neden olur. Öyleyse, herhangi bir nedenle yapmayın. Bir değişkene ihtiyacınız varsa, yeni bir değişken tanımlayın.
Her zaman değeri varsayılmaktadır __name__ olmak __main__ veya dosyanın adı. Bir kez daha bu varsayılan değerin değiştirilmesi, daha iyi sonuçlara yol açabileceğinden daha fazla kargaşaya neden olacak ve bu da çizginin aşağısında sorunlara neden olacaktır.
Genel olarak if __name__ == '__main__' komut dosyalarına dahil etmek iyi bir uygulama olarak kabul edilir .
Şimdi cevap vermek için if __name__ == '__main__' :
Şimdi __name__ olayların davranışlarının netleştiğini biliyoruz :
An if , verilen değerin doğru olması durumunda kod bloğunu içeren bir akış kontrol ifadesidir. __name__ Aldığını ya __main__ da alındığı dosya adını alabileceğini gördük .
Bunun anlamı, eğer o zaman __name__ eşitse __main__ , dosya ana dosya olmalı ve kodda içe aktarılan bir modül ya da paket değil, gerçekten çalışıyor olmalı (ya da yorumlayıcı ise).
Eğer gerçekten __name__ değerini alırsa , __main__ o zaman bu kod bloğunda ne varsa onu çalıştıracaktır.
Bu, eğer çalışan dosya ana dosya ise (ya da doğrudan tercümandan çalışıyorsanız) o koşulun yürütülmesi gerektiğini söyler. Bir paket ise o zaman olmamalı ve değer olmayacak __main__ .
__name__ Bir modülün adını tanımlamak için modüllerde de kullanılabilir.
__name__ Burada göstereceğim bazı , daha az yaygın ancak yararlı şeyler yapmak da mümkündür :
Yalnızca dosya bir modül veya paketse çalıştırma:
Dosya ana dosya ise bir koşulu çalıştırıyorsa, dosya ana dosyaysa bir başkası çalıştırıyorsa:
Ayrıca, kütüphaneleri ayrıntılı bir şekilde kullanmadan paketler ve modüller üzerinde çalıştırılabilir yardım işlevleri / yardımcı programları sağlamak için de kullanabilirsiniz.
Ayrıca, modüllerin komut satırından ana komut dosyaları olarak çalıştırılmasını da sağlar, bu da çok faydalı olabilir.
Bence cevabı derinlemesine ve basit kelimelerle kırmak en iyisidir:
__name__ : Python'daki her modül denilen özel bir özelliğe sahiptir __name__ . Modülün ismini döndüren yerleşik bir değişkendir.
__main__ : Diğer programlama dilleri gibi Python'da da yürütme giriş noktası vardır, yani ana. '__main__' üst düzey kodun yürütüldüğü kapsamın adıdır . Temel olarak bir Python modülünü kullanmanın iki yolu vardır: Doğrudan komut dosyası olarak çalıştırın veya içe aktarın. Bir modül bir komut dosyası olarak çalıştırıldığında, __name__ olarak ayarlanır __main__ .
Böylece, __name__ özniteliğin değeri __main__ , modül ana program olarak çalıştırıldığında ayarlanır . Aksi takdirde, değeri __name__ modülün adını içerecek şekilde ayarlanır.
Python dosyası komut satırından çağrıldığında özel bir şeydir. Bu genellikle "main ()" işlevini çağırmak veya örneğin komut satırı argümanları gibi diğer uygun başlangıç ​​kodlarını çalıştırmak için kullanılır.
Birkaç şekilde yazılabilir. Başka bir:
Bunu üretim kodunda kullanmanız gerektiğini söylemiyorum, ama "büyülü" bir şey olmadığını göstermek için hizmet ediyor if __name__ == '__main__' . Python dosyalarında bir ana işlevi çağırmak için iyi bir kuraldır.
Prof. Falken2013-01-242013-01-24 13:48:38Z
Sistemin (Python yorumlayıcısı) kaynak dosyalar (modüller) için sağladığı bazı değişkenler vardır. Değerlerini istediğiniz zaman alabilirsiniz, bu nedenle, __name__ değişkeni / niteliğine odaklanalım :
Python bir kaynak kod dosyası yüklediğinde, içinde bulunan tüm kodu çalıştırır. (Dosyada tanımlanan tüm yöntem ve işlevleri çağırmadığını, ancak bunları tanımladığını unutmayın.)
Tercüman kaynak kod dosyasını çalıştırmadan önce, o dosya için birkaç özel değişken tanımlar; __name__ , Python'un her kaynak kod dosyası için otomatik olarak tanımladığı özel değişkenlerden biridir.
Python bu kaynak kod dosyasını ana program olarak yüklüyorsa (yani çalıştırdığınız dosya), bu dosyanın özel __name__ değişkenini "__main__" değerine sahip olacak şekilde ayarlar .
Bu başka bir modülden içe aktarılıyorsa, __name__ bu modülün adına ayarlanacaktır.
Öyleyse, örneğinizdeki kısımda:
kod bloğu anlamına gelir:
sadece modülü doğrudan çalıştırdığınızda çalıştırılır; Başka bir modül çağırıyor / içeri alıyorsa, kod bloğu çalışmayacaktır çünkü __name__ değeri bu örnekte " ana " değerine eşit olmayacaktır .
if __name__ == "__main__": temelde üst düzey komut dosyası ortamıdır ve tercümanı belirtir ('ilk önce yürütülecek en yüksek önceliğe sahibim').
'__main__' üst düzey kodun yürütüldüğü kapsamın adıdır. Bir modül , standart girdiden, bir komut dosyasından veya etkileşimli bir komut satırından okunurken __name__ eşit olarak ayarlanır '__main__' .
The Gr8 Adakron2016-04-242016-04-24 08:23:01Z
Bu sayfadaki cevaplar boyunca çok fazla okudum. Eğer bir şey biliyorsan, kesin olarak bu cevapları anlayacaksın derdim, yoksa kafan karışık.
Kısacası, birkaç nokta bilmeniz gerekir:
import a eylem aslında "a" da çalıştırılabilecek her şeyi çalıştırıyor
Nokta 1 nedeniyle, içe aktarırken her şeyin "a" da çalıştırılmasını istemeyebilirsiniz.
2. noktadaki sorunu çözmek için, python bir durum kontrolü koymanıza izin verir
__name__ tüm .py modüllerinde örtük bir değişkendir; a.py alındığında, __name__ a.py modülünün değeri "a" dosya adına ayarlanır; a.py doğrudan "python a.py" kullanılarak çalıştırıldığında, a.py giriş noktası demektir __name__ , a.py modülünün değeri bir dizeye ayarlanır __main__
Python'un __name__ her modül için değişkeni nasıl ayarladığı mekanizmasına bağlı olarak , 3. noktaya nasıl ulaşacağınızı biliyor musunuz? Cevap oldukça kolay, değil mi? Bir if koşulu koyun if __name__ == "__main__": ... :; __name__ == "a" işlevsel ihtiyacınıza bağlı olarak bile koyabilirsiniz
Python'un özel olduğu önemli nokta 4. nokta! Gerisi sadece temel bir mantıktır.
öncelikle kodun doğrudan içe aktarılmasından kaynaklanacak olan içe aktarma kilitleme sorunlarından kaçınmak içindir . Dosyanız doğrudan çağrıldıysa çalıştırmak istersiniz ( durum böyledir), ancak kodunuz içe aktarılmışsa içe aktarma kilitleme sorunlarından kaçınmak için ithalatçı kodunuzu gerçek ana modülden girmelidir.https://stackoverflow.com/questions/46326059/ main() __name__ == "__main__"
Yan etki, birden çok giriş noktasını destekleyen bir metodolojide otomatik olarak oturum açmanızdır. Programınızı main() giriş noktası olarak çalıştırabilirsiniz , ancak mecbur değilsiniz . İken setup.py beklentiden main() , diğer araçlar alternatif giriş noktaları kullanırlar. Örneğin, dosyanızı bir gunicorn işlem olarak çalıştırmak için, a app() yerine bir işlev tanımladınız main() . Aynı şekilde setup.py , gunicorn kodunuzu içe aktarır, böylece içe aktarılırken bir şey yapmasını istemeyebilirsiniz (içe aktarma kilidi sorunu nedeniyle).
Yukarıdakiler için çıktı __main__ .
Yukarıdaki ifade doğrudur ve "doğrudan yöntemi" yazdırır . Bu sınıfı başka bir sınıfa içe aktarırlarsa, "direct method" yazmıyor çünkü içe aktarılırken ayarlanacağını varsayalım __name__ equal to "first model name" .
Janarthanan Ramu2016-06-222016-06-22 10:47:06Z
Dosyayı içe aktarılabilir bir modül kadar bir komut dosyası olarak da kullanılabilir duruma getirebilirsiniz .
fibo.py (adlı bir modül fibo )
Bu cevap Python'u öğrenen Java programcıları içindir. Her Java dosyası genellikle bir ortak sınıf içerir. Bu sınıfı iki şekilde kullanabilirsiniz:
Sınıfı diğer dosyalardan arayın. Çağıran programa aktarmanız yeterli.
Sınama amacıyla sınıfı tek başına çalıştırın.
İkinci durumda, sınıf, genel bir statik boş boşluk main () yöntemi içermelidir. Python'da bu amaç global olarak tanımlanmış etiket tarafından sunulmaktadır '__main__' .
Bu .py dosyası diğer .py dosyaları tarafından içe aktarılırsa, "if ifadesi" altındaki kod yürütülmez.
Eğer bu .py python this_py.py kabuk altında çalıştırılırsa veya Windows'ta çift tıklanırsa. "if ifadesi" altındaki kod çalıştırılacaktır.
Genellikle test için yazılmıştır.
Python'daki her modül isim olarak adlandırılan bir özelliğe sahiptir . Değeri adı özniteliği 'dir ana modül doğrudan çalıştırdığınızda'. Aksi halde, ismin değeri modülün ismidir.
Kısaca açıklamak için küçük bir örnek.
Bunu doğrudan olarak yapabiliriz.
Şimdi, diğer betiğin üstündeki betiği çağırdığımızı varsayalım.
Bu yüzden, yukarıdaki açıklama kendi kendini açıklar; eğer testi diğer betikten çağırdığınızda, eğer test.py içindeki döngü ismi çalıştırılmazsa.
Rishi Bansal2019-06-122019-06-12 09:28:39Z
Bir dosya oluşturun, a.py :
__name__ __main__ bu dosyanın her zaman doğrudan ana dosyanın bu olduğunu gösteren bir çalıştırıma eşittir .
Aynı dizinde başka bir dosya oluşturun, b.py :
Koş Bu yazdırılacaktır bir , yani dosyanın adını ithal edilmektedir .
Dolayısıyla, aynı dosyanın iki farklı davranışını göstermek için , bu yaygın olarak kullanılan bir numaradır:
eğer isim == ' ana ':
__name__ == '__main__': Oldukça sık görüyoruz .
Bir modülün ithal edilip edilmediğini kontrol eder.
Başka bir deyişle, if blok içindeki kod yalnızca kod doğrudan çalıştığında çalıştırılır. Buraya directly araçları not imported .
Modülün adını basan basit bir kod kullanarak ne yaptığını görelim:
Kodu doğrudan çalıştırırsak python test.py , modül adı __main__ :
Ali Hallaji2018-04-042018-04-04 14:32:34Z
Tüm cevaplar işlevselliği hemen hemen açıkladı. Ancak, kavramın daha da temizlenmesine yardımcı olabilecek kullanımına bir örnek vereceğim.
İki Python dosyanız olduğunu varsayalım, a.py ve b.py. Şimdi, a.py b.py dosyasını içe aktarır. Önce "import b.py" kodunun çalıştırıldığı a.py dosyasını çalıştırıyoruz. A.py kodunun geri kalanı çalışmadan önce, b.py dosyasındaki kodun tamamen çalışması gerekir.
B.py kodunda, b.py dosyasına özgü bir kod vardır ve onu çalıştırmak için b.py dosyasını içe aktarmış başka bir dosya (b.py dosyası dışında) istemiyoruz.
Demek bu kod satırını kontrol ediyor. Kodu çalıştıran ana dosya (yani, b.py) ise, bu durumda (a.py çalışan ana dosyadır), o zaman sadece kod çalıştırılır.
preetika mondal2018-05-042018-05-04 08:25:42Z
Python yorumlayıcısı belirli bir modülü çalıştırıyorsa, __name__ global değişken değere sahip olacaktır. "__main__"
Bu senaryoyu çalıştırdığınızda yazdırır beni görebilirsiniz
Bu dosyayı alırsanız, A'ya B dosyasına söyler ve B dosyasını uygularsanız A dosyasında if __name__ == "__main__" yanlış olur, bu yüzden yazdırır Beni göremezsiniz
Nikil Munireddy2019-07-302019-07-30 16:22:15Z
Basitçe, dosyayı C programlama dilinde main fonksiyon gibi çalıştırmak için giriş noktasıdır .
Mohammed Awney2019-02-032019-02-03 19:36:21Z
C ne yapar ??! ??! operatör mü?
Python'da “at” (@) sembolü ne işe yarar?
Ruby'de harita (&: name) ne anlama geliyor?
PHP 'var' anahtar sözcüğü ne işe yarar?
Q_OBJECT makrosu ne işe yarıyor? Neden tüm Qt nesneleri bu makroya ihtiyaç duyuyor?
“Genişlet” seçeneği grunt-Contrib-copy'te ne yapar? Örneklerin tümü onu kullanır ancak doktorlar ne yaptığı hakkında hiçbir şey söylemez
Denetleyicide filtre nasıl kullanılır?
Android'de% 20 saydam bir arka plan nasıl yapılır
Pandalar'daki SettingWithCopyWarning ile nasıl başa çıkılır?
NSZombieEnabled'ı Xcode 4'te nasıl kurarım?
Python's itertools.groupby () 'ı nasıl kullanırım?
Bir tam sayıyı 2'ye bölmek için kullanılacak daha iyi seçenek hangisidir?
ASCII ve Unicode arasındaki fark nedir?
super () yeni stil sınıfı için “TypeError: type olmalı, classobj değil” olmalı
Kilitlenme ve livelock arasındaki fark nedir?
'Subprocess' modülünü zaman aşımı ile kullanma