Pertanyaan Apa artinya jika __name__ == “__main__”: lakukan?


Apa yang dimaksud dengan if __name__ == "__main__": melakukan?

# 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))

4128
2018-01-07 04:11


asal


Jawaban:


Ketika penerjemah Python membaca file sumber, ia mengeksekusi semua kode yang ditemukan di dalamnya.

Sebelum mengeksekusi kode, ini akan menentukan beberapa variabel khusus. Sebagai contoh, jika interpreter Python menjalankan modul itu (file sumber) sebagai program utama, ia menetapkan yang khusus __name__ variabel untuk memiliki nilai "__main__". Jika file ini diimpor dari modul lain, __name__ akan diatur ke nama modul.

Dalam kasus skrip Anda, mari kita asumsikan bahwa itu dijalankan sebagai fungsi utama, mis. kamu mengatakan sesuatu seperti

python threading_example.py

pada baris perintah. Setelah menyiapkan variabel khusus, ia akan mengeksekusi import pernyataan dan memuat modul-modul itu. Ini kemudian akan mengevaluasi def memblokir, membuat objek fungsi dan membuat variabel yang disebut myfunction yang menunjuk ke objek fungsi. Kemudian akan membaca if pernyataan dan lihat itu __name__ tidak sama "__main__", sehingga akan mengeksekusi blok yang ditunjukkan di sana.

Salah satu alasan untuk melakukan ini adalah kadang-kadang Anda menulis modul (a .py file) di mana dapat dieksekusi secara langsung. Atau, itu juga dapat diimpor dan digunakan dalam modul lain. Dengan melakukan pemeriksaan utama, Anda dapat memiliki kode yang hanya dijalankan ketika Anda ingin menjalankan modul sebagai program dan tidak menjalankannya ketika seseorang hanya ingin mengimpor modul Anda dan memanggil fungsi Anda sendiri.

Lihat halaman ini untuk beberapa detail tambahan.


4407
2018-01-07 04:26



Saat skrip Anda dijalankan dengan meneruskannya sebagai perintah ke interpreter Python,

python myscript.py

semua kode yang berada di indentasi level 0 dijalankan. Fungsi dan kelas yang ditentukan, didefinisikan dengan baik, tetapi tidak ada kode yang dijalankan. Tidak seperti bahasa lain, tidak ada main() fungsi yang dijalankan secara otomatis - main() fungsi secara implisit semua kode di tingkat atas.

Dalam hal ini, kode level teratas adalah sebuah if blok. __name__ adalah variabel built-in yang mengevaluasi ke nama modul saat ini. Namun, jika modul sedang dijalankan secara langsung (seperti di myscript.py di atas), lalu __name__ alih-alih diatur ke string "__main__". Dengan demikian, Anda dapat menguji apakah skrip Anda dijalankan langsung atau diimpor oleh sesuatu yang lain dengan pengujian

if __name__ == "__main__":
    ...

Jika skrip Anda sedang diimpor ke modul lain, berbagai fungsi dan definisi kelasnya akan diimpor dan kode tingkat teratasnya akan dijalankan, tetapi kode di bagian selanjutnya dari if klausa di atas tidak akan berjalan karena kondisinya tidak terpenuhi. Sebagai contoh dasar, perhatikan dua skrip berikut:

# 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")

Sekarang, jika Anda memanggil interpreter sebagai

python one.py

Outputnya akan

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

Jika Anda lari two.py sebagai gantinya:

python two.py

Anda mendapatkan

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

Jadi, saat modul one dimuat, itu __name__ sama "one" dari pada "__main__".


1403
2018-01-07 04:28



Penjelasan paling sederhana untuk __name__ variabel (imho) adalah sebagai berikut:

Buat file-file berikut.

# a.py
import b

dan

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Menjalankannya akan memberi Anda output ini:

$ python a.py
Hello World from b!

Seperti yang Anda lihat, ketika modul diimpor, set Python globals()['__name__'] dalam modul ini ke nama modul.

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

Seperti yang Anda lihat, ketika file dijalankan, set Python globals()['__name__'] dalam file ini ke "__main__".


560
2018-01-07 11:35



Apa yang dimaksud dengan if __name__ == "__main__": melakukan?

Untuk menguraikan dasar-dasarnya:

  • Variabel global, __name__, dalam modul yang merupakan titik masuk ke program Anda, adalah '__main__'. Jika tidak, ini adalah nama yang Anda impor modulnya.

  • Jadi, kode di bawah if blok hanya akan berjalan jika modul adalah titik masuk ke program Anda.

  • Ini memungkinkan kode di modul untuk diimpor oleh modul lain, tanpa mengeksekusi blok kode di bawah pada impor.


Kenapa kita perlu ini?

Mengembangkan dan Menguji Kode Anda

Katakanlah Anda sedang menulis skrip Python yang dirancang untuk digunakan sebagai modul:

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

Kamu bisa uji modul dengan menambahkan panggilan fungsi ini ke bawah:

do_important()

dan menjalankannya (pada prompt perintah) dengan sesuatu seperti:

~$ python important.py

Masalah

Namun, jika Anda ingin mengimpor modul ke skrip lain:

import important

Pada impor, do_important fungsi akan dipanggil, jadi Anda mungkin akan mengomentari panggilan fungsi Anda, do_important(), di dasar.

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

Dan kemudian Anda harus ingat apakah Anda telah mengomentari panggilan fungsi tes Anda. Dan kerumitan ekstra ini berarti Anda cenderung lupa, membuat proses pengembangan Anda menjadi lebih merepotkan.

A Better Way

Itu __name__ poin variabel ke namespace di mana penerjemah Python kebetulan saat ini.

Di dalam modul yang diimpor, itu adalah nama modul itu.

Tetapi di dalam modul utama (atau sesi Python interaktif, misalnya penerjemah Baca, Eval, Print Loop, atau REPL) Anda menjalankan semuanya dari "__main__".

Jadi, jika Anda memeriksa sebelum mengeksekusi:

if __name__ == "__main__":
    do_important()

Dengan kode di atas, kode Anda hanya akan dijalankan ketika Anda menjalankannya sebagai modul utama (atau sengaja memanggilnya dari skrip lain).

Suatu Cara yang Lebih Baik

Ada cara Pythonic untuk memperbaiki hal ini.

Bagaimana jika kita ingin menjalankan proses bisnis ini dari luar modul?

Jika kita menempatkan kode yang ingin kita latih ketika kita mengembangkan dan menguji dalam fungsi seperti ini dan kemudian lakukan pengecekan kami '__main__' segera setelah:

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's our payoff idiom!
if __name__ == '__main__':
    main()

Kami sekarang memiliki fungsi terakhir untuk akhir modul kami yang akan berjalan jika kami menjalankan modul sebagai modul utama.

Ini akan memungkinkan modul beserta fungsi dan kelasnya diimpor ke skrip lain tanpa menjalankannya main berfungsi, dan juga akan memungkinkan modul (dan fungsi dan kelasnya) dipanggil ketika menjalankan dari yang berbeda '__main__' modul, yaitu

import important
important.main()

Idiom ini juga dapat ditemukan dalam dokumentasi Python dalam penjelasan tentang __main__ modul. Teks itu menyatakan:

Modul ini mewakili ruang lingkup (jika tidak anonim) di mana   interpreter menjalankan program utama - perintah membaca dari   input standar, dari file skrip, atau dari prompt interaktif. Saya t   adalah lingkungan di mana bait "naskah bersyarat" idiomatik   menyebabkan skrip dijalankan:

if __name__ == '__main__':
    main()

412
2017-11-23 04:38



if __name__ == "__main__"adalah bagian yang berjalan ketika skrip dijalankan dari (katakanlah) baris perintah menggunakan perintah seperti python myscript.py.


92
2018-01-07 04:14



Apa yang terjadi if __name__ == "__main__": melakukan?

__name__ adalah variabel global (dalam Python, global sebenarnya berarti di level modul) yang ada di semua ruang nama. Biasanya ini adalah nama modul (sebagai a str mengetik).

Sebagai satu-satunya kasus khusus, bagaimanapun, dalam proses Python apa pun yang Anda jalankan, seperti di mycode.py:

python mycode.py

namespace global yang dinyatakan anonim diberi nilai '__main__' untuk itu __name__.

Jadi, termasuk garis akhir

if __name__ == '__main__':
    main()
  • di akhir skrip mycode.py Anda,
  • ketika itu adalah modul entry-point primer yang dijalankan oleh proses Python,

akan menyebabkan skrip Anda ditentukan secara unik main berfungsi untuk dijalankan.

Manfaat lain menggunakan konstruksi ini: Anda juga dapat mengimpor kode Anda sebagai modul di skrip lain dan kemudian jalankan fungsi utama jika dan ketika program Anda memutuskan:

import mycode
# ... any amount of other code
mycode.main()

57
2017-10-14 20:22



Ada banyak hal yang berbeda di sini tentang mekanisme kode yang dimaksud, "Bagaimana", tetapi bagi saya tidak ada yang masuk akal sampai saya memahami "Mengapa". Ini harus sangat membantu para pemrogram baru.

Ambil file "ab.py":

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

Dan file kedua "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()

Apa sebenarnya yang dilakukan kode ini?

Ketika Anda mengeksekusi xy.py, kamu import ab. Pernyataan impor menjalankan modul segera pada impor, jadi abOperasi dijalankan sebelum sisa xy's. Setelah selesai ab, berlanjut dengan xy.

Interpreter melacak mana skrip yang berjalan dengan __name__. Ketika Anda menjalankan skrip - tidak peduli apa yang Anda beri nama - penerjemah menyebutnya "__main__", menjadikannya master atau skrip 'rumah' yang dikembalikan setelah menjalankan skrip eksternal.

Skrip lain yang dipanggil dari ini "__main__" skrip ditugaskan dengan nama file sebagai miliknya __name__ (misalnya., __name__ == "ab.py"). Oleh karena itu, garisnya if __name__ == "__main__": adalah tes penerjemah untuk menentukan apakah itu menafsirkan / menguraikan skrip 'rumah' yang awalnya dijalankan, atau apakah itu sementara mengintip ke skrip (eksternal) lain. Ini memberikan fleksibilitas kepada programmer untuk memiliki skrip yang berperilaku berbeda jika dijalankan secara langsung vs. dipanggil secara eksternal.

Mari kita melangkahi kode di atas untuk memahami apa yang terjadi, pertama-tama fokus pada baris yang tidak terindeks dan urutan yang muncul dalam skrip. Ingat fungsi itu - atau def - blok tidak melakukan apa-apa sendiri sampai mereka dipanggil. Apa yang mungkin dikatakan penerjemah jika bergumam pada dirinya sendiri:

  • Buka xy.py sebagai file 'rumah'; sebut saja "__main__" dalam __name__ variabel.
  • Impor dan buka file dengan __name__ == "ab.py".
  • Oh, sebuah fungsi. Saya akan mengingatnya.
  • Oke, fungsi a(); Saya baru saja mempelajarinya. Mencetak 'Fungsi dalam file ab'.
  • Akhir dari file; kembali ke "__main__"!
  • Oh, sebuah fungsi. Saya akan mengingatnya.
  • Yang lainnya.
  • Fungsi x(); ok, mencetak 'tugas periferal: mungkin berguna dalam proyek lain'.
  • Apa ini? Sebuah if pernyataan. Nah, syaratnya sudah terpenuhi (variabel __name__telah diatur untuk "__main__"), jadi saya akan memasukkan main() fungsi dan cetak 'fungsi utama: ini adalah tempat tindakannya'.

Dua baris bawah berarti: "Jika ini adalah "__main__" atau skrip 'home', jalankan fungsi yang dipanggil main()". Itu sebabnya kamu akan melihat a def main(): blokir bagian atas, yang berisi alur utama dari fungsionalitas skrip.

Mengapa mengimplementasikan ini?

Ingat apa yang saya katakan sebelumnya tentang pernyataan impor? Ketika Anda mengimpor modul, ia tidak hanya 'mengenali' dan menunggu instruksi lebih lanjut - ia benar-benar menjalankan semua operasi yang dapat dijalankan yang terkandung dalam skrip. Jadi, masukkan daging naskah Anda ke dalam main() berfungsi secara efektif mengkarantina, menempatkannya dalam isolasi sehingga tidak akan langsung berjalan ketika diimpor oleh skrip lain.

Sekali lagi, akan ada pengecualian, tetapi praktik umum adalah itu main() biasanya tidak dipanggil secara eksternal. Jadi Anda mungkin bertanya-tanya satu hal lagi: jika kita tidak menelepon main(), mengapa kita memanggil skrip sama sekali? Itu karena banyak orang struktur skrip mereka dengan fungsi yang berdiri sendiri yang dibangun untuk dijalankan independen dari sisa kode dalam file. Mereka kemudian disebut di tempat lain di tubuh naskah. Yang membawa saya ke ini:

Tetapi kode itu berfungsi tanpa itu

Ya itu betul. Fungsi-fungsi terpisah ini bisa dipanggil dari skrip in-line yang tidak terdapat di dalam main() fungsi. Jika Anda sudah terbiasa (seperti saya, dalam tahap awal belajar pemrograman) untuk membuat skrip in-line yang benar-benar sesuai dengan yang Anda butuhkan, dan Anda akan mencoba mencari tahu lagi jika Anda membutuhkan operasi itu lagi .. Anda tidak terbiasa dengan struktur internal semacam ini pada kode Anda, karena lebih rumit untuk dibuat dan tidak begitu intuitif untuk dibaca.

Tapi itu adalah skrip yang mungkin tidak dapat memiliki fungsi yang disebut secara eksternal, karena jika itu melakukannya akan segera mulai menghitung dan menetapkan variabel. Dan kemungkinan jika Anda mencoba untuk menggunakan kembali fungsi, skrip baru Anda terkait cukup dekat dengan yang lama sehingga akan ada variabel yang saling bertentangan.

Dalam memisahkan fungsi independen, Anda mendapatkan kemampuan untuk menggunakan kembali pekerjaan Anda sebelumnya dengan memanggilnya ke skrip lain. Misalnya, "example.py" mungkin mengimpor "xy.py" dan memanggil x(), memanfaatkan fungsi 'x' dari "xy.py". (Mungkin itu memanfaatkan huruf ketiga dari string teks yang diberikan; membuat array NumPy dari daftar angka dan mengkuadratkannya; atau menjauhkan permukaan 3D. Kemungkinannya tidak terbatas.)

(Sebagai samping, pertanyaan ini berisi jawaban oleh @kindall yang akhirnya membantu saya memahami - mengapa, bukan caranya. Sayangnya ini sudah ditandai sebagai duplikat yang ini, yang menurut saya adalah kesalahan.)


47
2017-09-29 04:33



Ketika ada pernyataan tertentu dalam modul kami (M.py) kami ingin dieksekusi ketika akan berjalan sebagai utama (bukan diimpor), kami dapat menempatkan pernyataan tersebut (uji-kasus, laporan cetak) di bawah ini ifblok.

Secara default (saat modul berjalan sebagai utama, bukan diimpor) __name__ variabel diatur ke "__main__", dan kapan akan diimpor __name__ variabel akan mendapatkan nilai yang berbeda, kemungkinan besar nama modul ('M'). Ini sangat membantu dalam menjalankan berbagai varian modul secara bersamaan, dan memisahkan pernyataan input & output spesifik mereka dan juga jika ada kasus uji.

Pendeknya, Gunakan ini 'if __name__ == "main" 'Blok untuk mencegah (tertentu) kode dijalankan ketika modul diimpor.


39
2018-04-03 14:09



Mari kita lihat jawabannya dengan cara yang lebih abstrak:

Misalkan kita memiliki kode ini di x.py:

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

Blok A dan B dijalankan ketika kita menjalankan "x.py".

Tetapi hanya blok A (dan bukan B) dijalankan ketika kita menjalankan modul lain, "y.py" misalnya, di mana xy diimpor dan kode dijalankan dari sana (seperti ketika fungsi di "x.py" adalah dipanggil dari y.py).


32
2018-01-20 17:48



Ketika Anda menjalankan Python interaktif lokal __name__ variabel diberi nilai __main__. Demikian juga, ketika Anda menjalankan modul Python dari baris perintah, daripada mengimpornya ke modul lain, itu __name__ atribut diberi nilai __main__, bukan nama sebenarnya dari modul. Dengan cara ini, modul dapat melihat sendiri __name__ nilai untuk menentukan sendiri bagaimana mereka digunakan, apakah sebagai dukungan untuk program lain atau sebagai aplikasi utama yang dijalankan dari baris perintah. Dengan demikian, idiom berikut cukup umum dalam modul Python:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

30
2017-12-11 11:23



Sederhananya, __name__ adalah variabel yang ditentukan untuk setiap skrip yang menentukan apakah skrip dijalankan sebagai modul utama atau dijalankan sebagai modul yang diimpor.

Jadi jika kita memiliki dua skrip;

#script1.py
print "Script 1's name: {}".format(__name__)

dan

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

Output dari mengeksekusi script1 adalah

Script 1's name: __main__

Dan output dari mengeksekusi script2 adalah:

Script1's name is script1
Script 2's name: __main__

Seperti yang Anda lihat, __name__ memberitahu kita kode mana yang merupakan modul 'utama'. Ini bagus, karena Anda dapat menulis kode dan tidak perlu khawatir tentang masalah struktural seperti di C / C ++, di mana, jika file tidak mengimplementasikan fungsi 'utama' maka tidak dapat dikompilasi sebagai file yang dapat dieksekusi dan jika itu dilakukan, itu tidak bisa digunakan sebagai perpustakaan.

Katakanlah Anda menulis skrip Python yang melakukan sesuatu yang hebat dan Anda menerapkan muatan kapal fungsi yang berguna untuk tujuan lain. Jika saya ingin menggunakannya, saya dapat mengimpor skrip Anda dan menggunakannya tanpa menjalankan program Anda (mengingat bahwa kode Anda hanya mengeksekusi dalam if __name__ == "__main__": konteks). Sedangkan di C / C ++ Anda harus membagi potongan-potongan itu ke dalam modul terpisah yang kemudian termasuk file. Bayangkan situasi di bawah ini;

Complicated importing in C

Panah adalah tautan impor. Untuk tiga modul masing-masing mencoba untuk memasukkan kode modul sebelumnya ada enam file (sembilan, menghitung file implementasi) dan lima tautan. Ini menyulitkan untuk memasukkan kode lain ke dalam proyek C kecuali jika dikompilasi secara khusus sebagai perpustakaan. Sekarang bayangkan untuk Python:

Elegant importing in Python

Anda menulis modul, dan jika seseorang ingin menggunakan kode Anda, mereka hanya mengimpornya dan __name__variabel dapat membantu memisahkan bagian yang dapat dieksekusi dari program dari bagian perpustakaan.


29
2017-10-15 09:07