Python içe aktardığımda modülümü neden çalıştırıyor ve nasıl durdurabilirim?


174

Ben 2 yoldan herhangi biriyle çalıştırılabilir inşa ediyorum bir Python programı var: ilk "dostça bir şekilde giriş için kullanıcı sorar ve sonra program aracılığıyla kullanıcı girdisi çalışır" python main.py "çağırmaktır. Diğer yol ise, tüm dost girdi toplama işleminden geçecek ve tek bir seferde program aracılığıyla bir dosyanın tüm girdi değerini çalıştıracak olan "python batch.py -file- " yi çağırmaktır .

Sorun "batch.py" çalıştırdığınızda "main.py" den bazı değişkenleri / yöntemleri / etc içe aktarması ve bu kodu çalıştırmasıdır:

import main

Programın ilk satırında, kodu "main.py" dosyasında çalıştırmaya çalıştığı için hemen hata verir.

Python'un içe aktardığım "ana" modülde bulunan kodu çalıştırmasını nasıl durdurabilirim?

Yanıtlar:


252

Bu Python böyle çalıştığını Çünkü - gibi anahtar classve defolan beyanları değil . Bunun yerine, bunlar gerçek canlı ifadelerdir . Eğer onlar yürütülmemiş olsaydı modül .. boş :-) olurdu

Her neyse, deyimsel yaklaşım:

# stuff to run always here such as class/def
def main():
    pass

if __name__ == "__main__":
   # stuff only to run when not called via 'import' here
   main()

Bkz nedir if __name__ == "__main__"için?

Ancak, importdüzenlenmekte olan modül üzerinde kaynak kontrolü gerektirir .

Mutlu kodlama.


1
sadece onaylamak için, yorumunuz "sadece 'burada' 'import' ile çağrılmadığında çalıştırılacak şeyler 'main () altında yazılacak komutları ifade eder, değil mi? Yoksa önemli değil mi ??
Goldname

@Goldname if ifadesinin içindeki kod içe aktarıldığında çalıştırılmaz, ancak kendi içindeki ana işlev tanımlanır ve bir içe aktarma yoluyla bile kullanıma hazırdır. Bu modül sadece çalıştırıldığında ana işlevi yürütür ve içe aktarılırsa çalıştırmaz. Her şey ne yapmak istediğinize bağlı. Başka bir yerde ana içindeki komutlara ihtiyacınız yoksa, bunları if'in içine yazın. Ama bana göre daha temiz görünüyor.
Felix

51

Python'un çalışma şekli nedeniyle, modüllerinizi içe aktarırken çalıştırması gerekir.

Modüldeki kodun içe aktarıldığında yürütülmesini önlemek için, ancak yalnızca doğrudan çalıştırıldığında, bunu bununla koruyabilirsiniz if:

if __name__ == "__main__":
    # this won't be run when imported

Bu kodu bir main()yönteme koymak isteyebilirsiniz , böylece dosyayı doğrudan yürütebilir veya modülü içe aktarabilir ve main(). Örneğin, bunun dosyada olduğunu varsayalım foo.py.

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

Bu program devam ederek python foo.pyveya başka bir Python betiğinden çalıştırılabilir:

import foo

...

foo.main()

12

if __name__ == '__main__'Deyimi kullan - __name__değeri '__main__'modül bir komut dosyası olarak çalıştırılıyorsa, içe aktarılmışsa modül adı olan özel bir değişkendir . Yani böyle bir şey yapardın

# imports
# class/function definitions
if __name__ == '__main__':
    # code here will only run when you invoke 'python main.py'

4

Maalesef bilmiyorsun. Bu, içe aktarım sözdiziminin nasıl çalıştığının bir parçasıdır ve hatırlanması önemlidir - hatırlama defaslında yürütülen bir şeydir, Python içe aktarmayı yürütmediyse, işlevsiz sıkışmış olursunuz.

Yine de dosyaya erişebildiğiniz için, hataya neyin neden olduğunu arayabilir ve görebilirsiniz. Hatanın olmasını önlemek için ortamınızı değiştirmek mümkün olabilir.


1
Not olarak: ortamın, hatanın önlenebileceği şekilde değiştirilmesinin bir yolu yoksa, belki farklı bir modül kullanmalısınız
cwallenpoole 29:11

4

Kodu bir işlevin içine koyun, siz işlevi çağırıncaya kadar çalışmaz. Bir ana fonksiyonunuz olmalıdır main.py. ifadesiyle:

if __name__ == '__main__':
  main()

Aradığınızda Sonra, fonksiyon çalışacaktır. İçe aktarırsanız , aktarılmaz . Ayrıca, netlik adına muhtemelen başka bir şeyle yeniden adlandırmalısınız .python main.pymain()main.pymain.py


3

Orada bir Python geliştirme öneriydi KEP 299 yerine amaçladık if __name__ == '__main__':ile deyim def __main__:, ancak reddedildi. Kullanırken nelerin akılda tutulacağını bilmek hala iyi bir okuma if __name__ = '__main__':.


2

"Main.py" dosyanızı şöyle yazabilirsiniz:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()

-1

importKodu çalıştırmadan kullanamazsınız ; değişkenlerinizi girebileceğiniz oldukça hızlı bir yol vardır; kullanarak numpy.savez, değişkenleri bir .npz dosyasında sayısal diziler olarak depolar. Daha sonra kullanarak değişkenleri yükleyebilirsiniz numpy.load.

Scipy belgelerinde tam açıklamaya bakın

Bunun yalnızca değişkenler ve değişkenler dizisi için geçerli olduğunu, yöntem vb. İçin geçerli olmadığını lütfen unutmayın.


-4

Main.py'den gereken işlevleri almayı mı deneyin? Yani,

from main import SomeFunction

Batch.py ​​işlevinde main.py işleviyle aynı işlevi adlandırmış olabilirsiniz ve main.py dosyasını içe aktardığınızda program batch.py ​​işlevi yerine main.py işlevini çalıştırır; yukarıdakileri yapmak bunu düzeltmelidir. Umuyorum.


En azından Windows'da değil.
Martín Coll

2
import mainanadan geçerli ad alanına her şeyi İçe aktarmaz. mainGeçerli ad alanına yalnızca tek bir sembol eklediğinden , çarpışmalar gerçekleşemez.
remram
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.