Bagaimana jika __name__ == “__main__”: lakukan?

6067

Dengan kode berikut, apa fungsinya 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))
Berbakti
sumber
Apakah if __name__ == "__main__":kondisi blok sudah usang / usang sejauh Python 3? Saya telah menemukan beberapa informasi yang menyatakan itu.
carloswm85
2
@ carloswm85 Itu tidak benar.
Giorgos Myrianthous

Jawaban:

6646

Setiap kali penerjemah Python membaca file sumber, itu melakukan dua hal:

  • itu menetapkan beberapa variabel khusus seperti __name__, dan kemudian

  • itu mengeksekusi semua kode yang ditemukan dalam file.

Mari kita lihat bagaimana ini bekerja dan bagaimana kaitannya dengan pertanyaan Anda tentang __name__pemeriksaan yang selalu kita lihat dalam skrip Python.

Contoh kode

Mari kita gunakan contoh kode yang sedikit berbeda untuk mengeksplorasi cara kerja impor dan skrip. Misalkan berikut ini dalam file bernama 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")

Variabel khusus

Ketika interpeter Python membaca file sumber, ia pertama-tama mendefinisikan beberapa variabel khusus. Dalam hal ini, kami peduli dengan __name__variabelnya.

Ketika Modul Anda Adalah Program Utama

Jika Anda menjalankan modul Anda (file sumber) sebagai program utama, mis

python foo.py

interpreter akan menetapkan string hard-coded "__main__"ke __name__variabel, yaitu

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

Ketika Modul Anda Diimpor Oleh Orang Lain

Di sisi lain, anggaplah beberapa modul lain adalah program utama dan itu mengimpor modul Anda. Ini berarti ada pernyataan seperti ini di program utama, atau di modul lain, program ini mengimpor:

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

Penerjemah akan mencari foo.pyfile Anda (bersama dengan mencari beberapa varian lainnya), dan sebelum menjalankan modul itu, ia akan menetapkan nama "foo"dari pernyataan impor ke __name__variabel, yaitu

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

Melaksanakan Kode Modul

Setelah variabel khusus diatur, penerjemah mengeksekusi semua kode dalam modul, satu pernyataan pada satu waktu. Anda mungkin ingin membuka jendela lain di samping dengan contoh kode sehingga Anda dapat mengikuti penjelasan ini.

Selalu

  1. Ini mencetak string "before import"(tanpa tanda kutip).

  2. Itu memuat mathmodul dan menugaskannya ke variabel yang disebut math. Ini sama dengan mengganti import mathdengan yang berikut ini (perhatikan bahwa __import__ini adalah fungsi tingkat rendah dalam Python yang mengambil string dan memicu impor aktual):

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

  2. Ini mengeksekusi defblok, membuat objek fungsi, kemudian menetapkan objek fungsi itu ke variabel yang disebut functionA.

  3. Ini mencetak string "before functionB".

  4. Itu mengeksekusi defblok kedua , membuat objek fungsi lain, kemudian menugaskannya ke variabel yang dipanggil functionB.

  5. Ini mencetak string "before __name__ guard".

Hanya Ketika Modul Anda Adalah Program Utama

  1. Jika modul Anda adalah program utama, maka ia akan melihat bahwa __name__memang diatur ke "__main__"dan memanggil dua fungsi, mencetak string "Function A"dan "Function B 10.0".

Hanya Saat Modul Anda Diimpor oleh Orang Lain

  1. ( Sebaliknya ) Jika modul Anda bukan program utama tetapi diimpor oleh yang lain, maka __name__akan menjadi "foo", bukan "__main__", dan itu akan melewati badan ifpernyataan.

Selalu

  1. Ini akan mencetak string "after __name__ guard"di kedua situasi.

Ringkasan

Singkatnya, inilah yang akan dicetak dalam dua kasus:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Mengapa Ini Bekerja Dengan Cara Ini?

Anda mungkin bertanya-tanya mengapa ada orang yang menginginkan ini. Nah, terkadang Anda ingin menulis .pyfile yang bisa digunakan oleh program lain dan / atau modul sebagai modul, dan juga bisa dijalankan sebagai program utama itu sendiri. Contoh:

  • Modul Anda adalah pustaka, tetapi Anda ingin memiliki mode skrip tempat menjalankan beberapa tes unit atau demo.

  • Modul Anda hanya digunakan sebagai program utama, tetapi memiliki beberapa pengujian unit, dan kerangka kerja pengujian bekerja dengan mengimpor .pyfile seperti skrip Anda dan menjalankan fungsi pengujian khusus. Anda tidak ingin itu mencoba menjalankan skrip hanya karena mengimpor modul.

  • Modul Anda sebagian besar digunakan sebagai program utama, tetapi juga menyediakan API yang ramah programmer untuk pengguna tingkat lanjut.

Di luar contoh-contoh itu, elegan bahwa menjalankan skrip dengan Python hanya menyiapkan beberapa variabel ajaib dan mengimpor skrip. "Menjalankan" skrip adalah efek samping dari mengimpor modul skrip.

Bahan untuk dipikirkan

  • Pertanyaan: Dapatkah saya memiliki beberapa __name__blok pemeriksaan? Jawaban: aneh melakukannya, tetapi bahasa tidak akan menghentikan Anda.

  • Misalkan berikut ini dalam foo2.py. Apa yang terjadi jika Anda mengatakan python foo2.pypada command-line? Mengapa?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Sekarang, cari tahu apa yang akan terjadi jika Anda menghapus __name__check-in foo3.py:
# 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")
  • Apa yang akan dilakukan bila digunakan sebagai skrip? Kapan diimpor sebagai modul?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")
Tuan Fooz
sumber
14
Karena penasaran: Apa yang terjadi jika saya menjalankan subprocess.run('foo_bar.py')skrip python? Saya kira itu foo_barakan dimulai dengan __name__ = '__main__'seperti ketika saya mengetikkan foo_bar.pycmd secara manual. Apakah itu masalahnya? Mempertimbangkan Jawab @MrFooz 'seharusnya tidak ada masalah dalam melakukan ini dan memiliki modul "utama" sebanyak yang saya mau. Bahkan mengubah __name__nilai atau memiliki beberapa contoh yang dibuat secara independen (atau contoh yang dibuat oleh satu sama lain subprocess) berinteraksi satu sama lain harus menjadi bisnis seperti biasa untuk Python. Apakah saya melewatkan sesuatu?
hajef
12
@ hajef Anda benar tentang cara kerja berbagai hal subprocess.run. Oleh karena itu, cara berbagi kode antar skrip yang umumnya lebih baik adalah dengan membuat modul dan meminta skrip memanggil modul yang dibagikan daripada saling memanggil sebagai skrip. Sulit untuk men-debug subprocess.runpanggilan karena sebagian besar debugger tidak melewati batas proses, itu dapat menambah overhead sistem non-sepele untuk membuat dan menghancurkan proses tambahan, dll.
Mr Fooz
4
Saya memiliki keraguan dalam contoh foo2.py di bagian makanan untuk berpikir. Apa yang dilakukan dari fungsi impor foo2.py? Dalam pandangan saya itu hanya mengimpor foo2.py dari functionB
user471651
1
@ MrFooz Saya tidak pernah bermaksud melakukan hal seperti ini xD. Baru saja terlintas di pikiran saya dan saya menyadari bahwa itu cukup aneh untuk mungkin membantu ppl. membungkus pikiran mereka di sekitar hal semacam ini. @ user471651 Mengapa harus from foo2 import functionBmengimpor foo2 dari functionB? Itu liuk semantik. from module import methodmengimpor metode dari modul.
hajef
2
Salah satu modul yang dapat mengimpor kode Anda adalah multiprocessing, khususnya membuat tes ini diperlukan pada Windows.
Yann Vernier
1801

Saat skrip Anda dijalankan dengan meneruskannya sebagai perintah ke juru bahasa Python,

python myscript.py

semua kode yang berada pada level lekukan 0 dijalankan. Fungsi dan kelas yang didefinisikan adalah, well, terdefinisi, tetapi tidak ada kodenya yang dijalankan. Tidak seperti bahasa lain, tidak ada main()fungsi yang dijalankan secara otomatis - main()fungsi ini secara implisit semua kode di tingkat atas.

Dalam hal ini, kode tingkat atas adalah ifblok. __name__adalah variabel bawaan yang mengevaluasi nama modul saat ini. Namun, jika modul dijalankan langsung (seperti di myscript.pyatas), maka __name__alih-alih diatur ke string "__main__". Dengan demikian, Anda dapat menguji apakah skrip Anda dijalankan secara 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 atasnya akan dieksekusi, tetapi kode di badan ifklausa di atas tidak akan berjalan karena kondisinya tidak bertemu. Sebagai contoh dasar, pertimbangkan 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 penerjemah sebagai

python one.py

Outputnya adalah

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

Jika Anda menjalankan two.pysebaliknya:

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, ketika modul onedimuat, hasilnya __name__sama dengan "one"bukan "__main__".

Adam Rosenfield
sumber
Jawaban yang luar biasa, ini adalah jawaban yang paling jelas menurut saya. +1!
TheTechRobo36414519
+1 untuk cara berpikir seperti itu: baris indentasi pertama dijalankan hanya pada awalnya, sampai Anda menjalankan fungsi pada baris pertama
Elijah Mock
719

Penjelasan paling sederhana untuk __name__variabel (imho) adalah sebagai berikut:

Buat 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__

Menjalankan mereka akan memberi Anda hasil ini:

$ python a.py
Hello World from b!

Seperti yang Anda lihat, ketika modul diimpor, Python menetapkan globals()['__name__']modul ini ke nama modul. Juga, setelah mengimpor semua kode dalam modul sedang dijalankan. Sebagai ifmengevaluasi pernyataan untuk Falsebagian ini tidak dijalankan.

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

Seperti yang Anda lihat, ketika sebuah file dieksekusi, Python menetapkan globals()['__name__']file ini ke "__main__". Kali ini, ifpernyataan dievaluasi untuk Truedan sedang dijalankan.

pi.
sumber
513

Apa yang if __name__ == "__main__":dilakukan?

Untuk menguraikan dasar-dasarnya:

  • Variabel global __name__,, dalam modul yang merupakan titik masuk ke program Anda, adalah '__main__'. Kalau tidak, itu nama tempat Anda mengimpor modul.

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

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


Mengapa kita memerlukan 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"""

Anda dapat menguji 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_importantfungsi akan dipanggil, jadi Anda mungkin akan mengomentari panggilan fungsi Anda do_important(),, di bagian bawah.

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

Dan kemudian Anda harus ingat apakah Anda sudah mengomentari panggilan fungsi pengujian atau tidak. Dan kompleksitas ekstra ini berarti Anda cenderung lupa, membuat proses pengembangan Anda lebih menyusahkan.

A Better Way

The __name__variabel poin ke namespace mana pun interpreter Python terjadi menjadi saat ini.

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

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

Jadi, jika Anda memeriksa sebelum mengeksekusi:

if __name__ == "__main__":
    do_important()

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

Suatu Cara Yang Lebih Baik

Ada cara Pythonic untuk memperbaiki ini, meskipun.

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

Jika kita meletakkan kode yang ingin kita gunakan saat kita mengembangkan dan menguji dalam fungsi seperti ini dan kemudian melakukan pemeriksaan untuk '__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 akhir untuk akhir modul kami yang akan berjalan jika kami menjalankan modul sebagai modul utama.

Ini akan memungkinkan modul dan fungsinya dan kelas untuk diimpor ke skrip lain tanpa menjalankan mainfungsi, dan juga akan memungkinkan modul (dan fungsi dan kelasnya) dipanggil ketika menjalankan dari '__main__'modul yang berbeda , yaitu

import important
important.main()

Ungkapan ini juga dapat ditemukan dalam dokumentasi Python dalam penjelasan __main__modul. Teks itu menyatakan:

Modul ini mewakili ruang lingkup (jika tidak anonim) di mana program utama penerjemah dijalankan - perintah dibaca baik dari input standar, dari file skrip, atau dari prompt interaktif. Inilah lingkungan di mana bait "naskah kondisional" idiomatik menyebabkan sebuah skrip dijalankan:

if __name__ == '__main__':
    main()
Aaron Hall
sumber
125

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

Harley Holcombe
sumber
2
Mengapa file helloworld.pydengan hanya print("hello world")di dalamnya dapat berjalan dengan perintah python helloworld.pybahkan ketika tidak ada if __name__ == "__main__"?
hi15
83

Apa yang if __name__ == "__main__":harus dilakukan

__name__adalah variabel global (dalam Python, global sebenarnya berarti pada tingkat modul ) yang ada di semua ruang nama. Biasanya nama modul (sebagai strtipe).

Namun, sebagai satu-satunya kasus khusus, dalam proses Python apa pun yang Anda jalankan, seperti pada mycode.py:

python mycode.py

namespace global yang anonim diberikan nilai '__main__'ke __name__.

Jadi, termasuk baris terakhir

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

akan menyebabkan mainfungsi skrip Anda yang unik berjalan.

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

import mycode
# ... any amount of other code
mycode.main()
Aaron Hall
sumber
72

Ada banyak perbedaan di sini tentang mekanisme kode yang dimaksud, "Bagaimana", tetapi bagi saya tidak ada yang masuk akal sampai saya memahami "Mengapa". Ini harus sangat membantu bagi programmer 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 yang sebenarnya dilakukan kode ini?

Ketika Anda mengeksekusi xy.py, Anda import ab. Pernyataan impor menjalankan modul segera pada impor, sehingga aboperasi dapat dijalankan sebelum sisa dari xy. Setelah selesai denganab , dilanjutkan dengan xy.

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

Setiap skrip lain yang dipanggil dari "__main__"skrip ini akan diberi nama file sebagai __name__(mis., __name__ == "ab.py"). Karena itu, garisif __name__ == "__main__": adalah tes juru bahasa untuk menentukan apakah itu menafsirkan / menguraikan skrip 'rumah' yang awalnya dieksekusi, atau jika sementara mengintip ke skrip lain (eksternal). Ini memberikan fleksibilitas kepada programmer untuk membuat skrip berperilaku berbeda jika dijalankan secara langsung vs. disebut secara eksternal.

Mari kita melangkahi kode di atas untuk memahami apa yang terjadi, dengan fokus pertama pada baris yang tidak terindentasi dan urutan yang muncul dalam skrip. Ingatlah bahwa fungsi - atau def- blok tidak melakukan apa pun sampai mereka dipanggil. Apa yang penerjemah katakan jika bergumam sendiri:

  • Buka xy.py sebagai file 'home'; sebut saja "__main__"dalam __name__variabel.
  • Impor dan buka file dengan __name__ == "ab.py".
  • Oh, sebuah fungsi. Saya akan ingat itu.
  • Ok, berfungsi a(); Saya baru tahu itu. Mencetak ' Fungsi dalam file ab '.
  • Akhir file; kembali ke "__main__"!
  • Oh, sebuah fungsi. Saya akan ingat itu.
  • Yang lainnya.
  • Fungsi x(); ok, mencetak ' tugas sampingan: mungkin berguna di proyek lain '.
  • Apa ini? Sebuah ifpernyataan. Nah, kondisinya telah terpenuhi (variabel __name__telah diatur ke "__main__"), jadi saya akan memasukkan main()fungsi dan mencetak ' fungsi utama: ini adalah tempat tindakan '.

Dua baris bawah berarti: "Jika ini adalah "__main__"skrip atau 'rumah', jalankan fungsi yang disebut main()". Itu sebabnya Anda akan melihat def main():blok di bagian atas, yang berisi aliran utama fungsi skrip.

Mengapa menerapkan ini?

Ingat apa yang saya katakan sebelumnya tentang pernyataan impor? Ketika Anda mengimpor modul, modul itu tidak hanya 'mengenalinya' dan menunggu instruksi lebih lanjut - modul ini benar-benar menjalankan semua operasi yang dapat dieksekusi yang terdapat dalam skrip. Jadi, menempatkan daging skrip Anda ke dalam main()fungsi secara efektif mengkarantina, menempatkannya dalam isolasi sehingga tidak akan langsung berjalan ketika diimpor oleh skrip lain.

Sekali lagi, akan ada pengecualian, tetapi praktik umum yang 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 menyusun skrip mereka dengan fungsi mandiri yang dibangun untuk dijalankan secara independen dari sisa kode dalam file. Mereka kemudian dipanggil di tempat lain di tubuh skrip. Yang membawa saya ke ini:

Tapi kodenya bekerja tanpa itu

Ya itu betul. Fungsi-fungsi terpisah ini dapat dipanggil dari skrip in-line yang tidak terdapat di dalam amain() fungsi. Jika Anda terbiasa (seperti saya, dalam tahap awal pembelajaran saya pemrograman) untuk membangun skrip in-line yang melakukan persis apa yang Anda butuhkan, dan Anda akan mencoba mencari tahu lagi jika Anda memerlukan operasi itu lagi .. Nah, Anda tidak terbiasa dengan struktur internal semacam ini untuk kode Anda, karena lebih rumit untuk dibangun dan tidak intuitif untuk dibaca.

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

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

(Sebagai tambahan, pertanyaan ini berisi jawaban oleh @kindall yang akhirnya membantu saya untuk memahami - mengapa, bukan bagaimana. Sayangnya itu telah ditandai sebagai duplikat dari yang ini , yang saya pikir merupakan kesalahan.)

joechoj
sumber
52

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

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

Singkatnya , gunakan if __name__ == "main"blok ' ' ini untuk mencegah kode (tertentu) dijalankan ketika modul diimpor.

Nabeel Ahmed
sumber
43

Sederhananya, __name__adalah variabel yang ditentukan untuk setiap skrip yang mendefinisikan apakah skrip sedang dijalankan sebagai modul utama atau sedang 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__beri tahu kami kode mana yang merupakan modul 'utama'. Ini bagus, karena Anda hanya bisa menulis kode dan tidak perlu khawatir tentang masalah struktural seperti di C / C ++, di mana, jika file tidak menerapkan fungsi 'utama' maka tidak dapat dikompilasi sebagai yang dapat dieksekusi dan jika itu, maka tidak dapat digunakan sebagai perpustakaan.

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

Impor rumit di C

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

Impor elegan dengan Python

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

redbandit
sumber
2
Ilustrasi C / C ++ salah: 3 kali nama unit yang sama ( file1 ).
Wolf
40

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.

Tapi hanya blok A (dan bukan B) dijalankan ketika kita menjalankan modul lain, y.pymisalnya, di mana x.pydiimpor dan kode dijalankan dari sana (seperti ketika fungsi di x.pydipanggil dari y.py).

Alisa
sumber
1
Saya tidak dapat mengedit posting (minimal 6 karakter jika diperlukan perubahan). Baris 14 memiliki 'xy' daripada 'x.py'.
alwaysLearning
35

Ketika Anda menjalankan Python secara interaktif, __name__variabel lokal diberi nilai __main__. Demikian juga, ketika Anda menjalankan modul Python dari baris perintah, alih-alih mengimpornya ke modul lain, __name__atributnya diberi nilai __main__, bukan nama sebenarnya dari modul. Dengan cara ini, modul dapat melihat __name__nilainya sendiri untuk menentukan sendiri bagaimana mereka digunakan, apakah sebagai dukungan untuk program lain atau sebagai aplikasi utama yang dieksekusi 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.
Zain
sumber
34

Mempertimbangkan:

if __name__ == "__main__":
    main()

Ia memeriksa apakah __name__atribut skrip Python adalah "__main__". Dengan kata lain, jika program itu sendiri dieksekusi, atributnya akan __main__, sehingga program tersebut akan dieksekusi (dalam hal ini themain() fungsinya).

Namun, jika skrip Python Anda digunakan oleh modul, kode apa pun di luar ifpernyataan akan dieksekusi, jadi if \__name__ == "\__main__"digunakan hanya untuk memeriksa apakah program digunakan sebagai modul atau tidak, dan karena itu memutuskan apakah akan menjalankan kode.

Larry
sumber
sepertinya sudah terlalu lama untuk menulis jawaban bercahaya +1
snr
27

Sebelum menjelaskan apa pun tentang if __name__ == '__main__'itu, penting untuk memahami apa __name__itu dan apa fungsinya.

Apa __name__?

__name__adalah DunderAlias - dapat dianggap sebagai variabel global (dapat diakses dari modul) dan berfungsi dengan cara yang mirip dengan global.

Ini adalah string (global seperti yang disebutkan di atas) seperti yang ditunjukkan oleh type(__name__)(menghasilkan <class 'str'>), dan merupakan standar bawaan untuk versi Python 3 dan Python 2 .

Dimana:

Ini tidak hanya dapat digunakan dalam skrip tetapi juga dapat ditemukan di interpreter dan modul / paket.

Penerjemah:

>>> print(__name__)
__main__
>>>

Naskah:

test_file.py :

print(__name__)

Yang menghasilkan __main__

Modul atau paket:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Yang menghasilkan somefile

Perhatikan bahwa ketika digunakan dalam suatu paket atau modul, __name__ambil nama file tersebut. Jalur modul atau paket sebenarnya tidak diberikan, tetapi memiliki DunderAlias ​​sendiri __file__, yang memungkinkan untuk ini.

Anda harus melihat bahwa, di mana __name__, di mana file utama (atau program) akan selalu kembali __main__, dan jika itu adalah modul / paket, atau apa pun yang menjalankan beberapa skrip Python lainnya, akan mengembalikan nama file di mana itu berasal dari.

Praktek:

Menjadi variabel berarti nilainya dapat ditimpa ("bisa" tidak berarti "harus"), menimpa nilai __name__akan menghasilkan kurangnya keterbacaan. Jadi jangan lakukan itu, dengan alasan apa pun. Jika Anda membutuhkan variabel, tentukan variabel baru.

Itu selalu diasumsikan bahwa nilai __name__menjadi __main__atau nama file. Sekali lagi mengubah nilai default ini akan menyebabkan lebih banyak kebingungan bahwa itu akan berbuat baik, menyebabkan masalah lebih jauh ke depan.

contoh:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

Ini dianggap praktik yang baik secara umum untuk memasukkan if __name__ == '__main__'skrip dalam.

Sekarang untuk menjawab if __name__ == '__main__':

Sekarang kita tahu perilaku __name__menjadi lebih jelas:

Sebuah ifadalah pernyataan kontrol aliran yang berisi blok kode akan mengeksekusi jika nilai yang diberikan adalah benar. Kami telah melihatnya__name__ dapat mengambil salah satu __main__atau nama file dari mana ia diimpor.

Ini berarti bahwa jika __name__sama dengan__main__ maka file tersebut harus file utama dan harus benar-benar berjalan (atau itu adalah juru bahasa), bukan modul atau paket yang diimpor ke dalam skrip.

Jika memang __name__mengambil nilai__main__ maka apa pun yang ada di blok kode itu akan dijalankan.

Ini memberitahu kita bahwa jika file yang dijalankan adalah file utama (atau Anda menjalankan dari penerjemah secara langsung) maka syarat itu harus dijalankan. Jika itu sebuah paket maka seharusnya tidak, dan nilainya tidak akan __main__.

Modul:

__name__ juga dapat digunakan dalam modul untuk menentukan nama modul

Varian:

Dimungkinkan juga untuk melakukan hal-hal lain yang kurang umum tetapi bermanfaat __name__, beberapa akan saya tunjukkan di sini:

Hanya mengeksekusi jika file tersebut adalah modul atau paket:

if __name__ != '__main__':
    # Do some useful things 

Menjalankan satu kondisi jika file tersebut adalah yang utama dan yang lainnya jika tidak:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

Anda juga dapat menggunakannya untuk menyediakan fungsi / utilitas bantuan yang dapat dijalankan pada paket dan modul tanpa penggunaan pustaka yang rumit.

Ini juga memungkinkan modul dijalankan dari baris perintah sebagai skrip utama, yang juga bisa sangat berguna.

Simon
sumber
25

Saya pikir yang terbaik adalah memecahkan jawaban secara mendalam dan dengan kata-kata sederhana:

__name__: Setiap modul dengan Python memiliki atribut khusus yang disebut __name__ . Ini adalah variabel bawaan yang mengembalikan nama modul.

__main__: Seperti bahasa pemrograman lain, Python juga memiliki titik masuk eksekusi, yaitu utama. '__main__' adalah nama ruang lingkup di mana kode tingkat atas dijalankan . Pada dasarnya Anda memiliki dua cara menggunakan modul Python: Jalankan secara langsung sebagai skrip, atau impor. Saat modul dijalankan sebagai skrip, modul __name__ini disetel ke __main__.

Dengan demikian, nilai __name__atribut diatur ke __main__saat modul dijalankan sebagai program utama. Kalau tidak, nilai __name__ diatur untuk berisi nama modul.

Inconnu
sumber
23

Ini khusus untuk ketika file Python dipanggil dari baris perintah. Ini biasanya digunakan untuk memanggil fungsi "main ()" atau menjalankan kode startup lain yang sesuai, seperti argumen commandline yang menangani misalnya.

Itu bisa ditulis dalam beberapa cara. Lainnya adalah:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

Saya tidak mengatakan Anda harus menggunakan ini dalam kode produksi, tetapi ini berfungsi untuk menggambarkan bahwa tidak ada yang "ajaib" tentang itu if __name__ == '__main__'. Ini adalah konvensi yang bagus untuk menjalankan fungsi utama dalam file Python.

Kontrak Prof. Falken dilanggar
sumber
7
Saya akan mempertimbangkan bentuk buruk ini karena Anda 1) mengandalkan efek samping dan 2) menyalahgunakan and. anddigunakan untuk memeriksa apakah dua pernyataan boolean keduanya benar. Karena Anda tidak tertarik pada hasil dari and, ifpernyataan yang lebih jelas mengomunikasikan niat Anda.
jpmc26
8
Mengesampingkan pertanyaan apakah mengeksploitasi perilaku hubung singkat operator boolean sebagai mekanisme kontrol aliran adalah gaya yang buruk atau tidak, masalah yang lebih besar adalah bahwa ini tidak menjawab pertanyaan sama sekali .
Mark Amery
@MarkAmery haha, sheesh, sekarang sudah. 😊
Kontrak Prof. Falken dilanggar
19

Ada sejumlah variabel yang disediakan oleh sistem (juru bahasa Python) untuk file sumber (modul). Anda bisa mendapatkan nilainya kapan saja, jadi, izinkan kami fokus pada __name__ variabel / atribut :

Ketika Python memuat file kode sumber, ia mengeksekusi semua kode yang ditemukan di dalamnya. (Perhatikan bahwa ia tidak memanggil semua metode dan fungsi yang didefinisikan dalam file, tetapi ia mendefinisikannya.)

Namun, sebelum penerjemah mengeksekusi file kode sumber, ia mendefinisikan beberapa variabel khusus untuk file itu; __nama__ adalah salah satu variabel khusus yang didefinisikan secara otomatis oleh Python untuk setiap file kode sumber.

Jika Python memuat file kode sumber ini sebagai program utama (yaitu file yang Anda jalankan), maka ia menetapkan variabel __name__ khusus untuk file ini untuk memiliki nilai "__main__" .

Jika ini sedang diimpor dari modul lain, __name__ akan diatur ke nama modul itu.

Jadi, dalam contoh Anda sebagian:

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

berarti bahwa blok kode:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

akan dieksekusi hanya ketika Anda menjalankan modul secara langsung; blok kode tidak akan dijalankan jika modul lain memanggil / mengimpornya karena nilai __name__ tidak akan sama dengan " main " dalam contoh khusus itu.

Semoga ini bisa membantu.

codewizard
sumber
17

if __name__ == "__main__": pada dasarnya adalah lingkungan skrip tingkat atas, dan menetapkan juru bahasa bahwa ('Saya memiliki prioritas tertinggi untuk dieksekusi terlebih dahulu').

'__main__'adalah nama ruang lingkup di mana kode tingkat atas dijalankan. Modul __name__diatur sama dengan '__main__'ketika dibaca dari input standar, skrip, atau dari prompt interaktif.

if __name__ == "__main__":
    # Execute only if run as a script
    main()
Adakron Gr8
sumber
17

Saya telah membaca banyak sekali jawaban di halaman ini. Saya akan mengatakan, jika Anda mengetahui hal itu, pasti Anda akan mengerti jawaban itu, jika tidak, Anda masih bingung.

Singkatnya, Anda perlu tahu beberapa hal:

  1. import a action sebenarnya menjalankan semua yang bisa dijalankan dalam "a"

  2. Karena poin 1, Anda mungkin tidak ingin semuanya dijalankan dalam "a" saat mengimpornya

  3. Untuk mengatasi masalah di poin 2, python memungkinkan Anda untuk melakukan pemeriksaan kondisi

  4. __name__merupakan variabel implisit dalam semua .pymodul; saat a.pydiimpor, nilai __name__dari a.pymodul diatur untuk nama file-nya " a"; ketika a.pydijalankan langsung menggunakan " python a.py", yang berarti a.pyadalah entry point, maka nilai __name__dari a.pymodul diatur ke string__main__

  5. Berdasarkan mekanisme bagaimana python mengatur variabel __name__untuk setiap modul, apakah Anda tahu cara mencapai poin 3? Jawabannya cukup mudah, bukan? Masukan kondisi jika: if __name__ == "__main__": ...; Anda bahkan dapat menaruh jika __name__ == "a"tergantung pada kebutuhan fungsional Anda

Hal penting yang menjadi istimewa python adalah poin 4! Sisanya hanya logika dasar.

mendongkrak
sumber
1
Ya, poin 1 sangat penting untuk dipahami. Dari situ, kebutuhan akan mekanisme ini menjadi jelas.
Eureka
16

Mempertimbangkan:

print __name__

Output untuk di atas adalah __main__.

if __name__ == "__main__":
  print "direct method"

Pernyataan di atas benar dan mencetak "metode langsung" . Misalkan jika mereka mengimpor kelas ini di kelas lain itu tidak mencetak "metode langsung" karena, saat mengimpor, itu akan ditetapkan __name__ equal to "first model name".

Janarthanan Ramu
sumber
14

Anda dapat membuat file dapat digunakan sebagai skrip dan juga modul yang dapat diimpor .

fibo.py (nama modul fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Referensi: https://docs.python.org/3.5/tutorial/modules.html

kgf3JfUtW
sumber
14

Alasan untuk

if __name__ == "__main__":
    main()

terutama untuk menghindari masalah kunci impor yang akan timbul dari memiliki kode yang diimpor secara langsung . Anda ingin main()menjalankan jika file Anda secara langsung dipanggil (itu yang __name__ == "__main__"terjadi), tetapi jika kode Anda diimpor maka importir harus memasukkan kode Anda dari modul utama yang benar untuk menghindari masalah kunci impor.

Efek sampingnya adalah Anda secara otomatis masuk ke metodologi yang mendukung banyak titik masuk. Anda dapat menjalankan program Anda menggunakan main()sebagai titik masuk, tetapi Anda tidak harus melakukannya . Saat setup.pymengharapkan main(), alat lain menggunakan titik masuk alternatif. Misalnya, untuk menjalankan file Anda sebagai suatu gunicornproses, Anda mendefinisikan suatu app()fungsi alih-alih a main(). Seperti halnya setup.py, gunicornimpor kode Anda sehingga Anda tidak ingin melakukan apa-apa saat sedang diimpor (karena masalah kunci impor).

personal_cloud
sumber
3
Baik untuk belajar tentang kunci impor . Bisakah Anda jelaskan masuk ke metodologi yang [...] berpisah sedikit lebih?
Wolf
1
@ Serigala: Tentu. Saya telah menambahkan beberapa kalimat tentang metodologi titik masuk ganda.
personal_cloud
11

Jawaban ini untuk programmer Java yang belajar Python. Setiap file Java biasanya berisi satu kelas publik. Anda dapat menggunakan kelas itu dalam dua cara:

  1. Panggil kelas dari file lain. Anda hanya perlu mengimpornya di program panggilan.

  2. Jalankan kelas berdiri sendiri, untuk tujuan pengujian.

Untuk kasus terakhir, kelas harus berisi metode public void main () statis. Dalam Python tujuan ini dilayani oleh label yang didefinisikan secara global '__main__'.

Raja
sumber
11

Kode di bawah if __name__ == '__main__': hanya akan dieksekusi jika modul dipanggil sebagai skrip .

Sebagai contoh, pertimbangkan modul berikut my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

Kemungkinan 1: Impor my_test_module.pydalam modul lain

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Sekarang jika Anda memohon main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Perhatikan bahwa hanya print()pernyataan tingkat atas di my_test_moduledieksekusi.


Kemungkinan kedua: Aktifkan my_test_module.pysebagai skrip

Sekarang jika Anda menjalankan my_test_module.pysebagai skrip Python, kedua print()pernyataan tersebut akan dikecualikan:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'
Giorgos Myrianthous
sumber
10

Setiap modul dalam python memiliki atribut yang disebut __name__. Nilai __name__ atribut adalah __main__ ketika modul dijalankan secara langsung, seperti python my_module.py. Kalau tidak (seperti ketika Anda mengatakan import my_module) nilai __name__ adalah nama modul.

Contoh kecil untuk dijelaskan secara singkat.

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

Kami dapat menjalankan ini secara langsung sebagai

python test.py  

Keluaran

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Sekarang anggaplah kita memanggil skrip di atas dari skrip lain

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

Ketika Anda menjalankan ini

python external_calling.py

Keluaran

42
I am inside hello_world
test

Jadi, di atas cukup jelas bahwa ketika Anda memanggil tes dari skrip lain, jika loop __name__in test.pytidak akan dijalankan.

Rishi Bansal
sumber
6

Jika file .py ini diimpor oleh file .py lainnya, kode di bawah "pernyataan jika" tidak akan dieksekusi.

Jika .py ini dijalankan oleh di python this_py.pybawah shell, atau klik dua kali pada Windows. kode di bawah "pernyataan jika" akan dieksekusi.

Biasanya ditulis untuk pengujian.

pah8J
sumber
6

Jika interpreter python menjalankan modul tertentu maka __name__variabel global akan memiliki nilai"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

Saat Anda menjalankan skrip ini, Anda dapat melihat saya

Sebuah

Jika Anda mengimpor file ini, katakan A ke file B dan jalankan file B maka if __name__ == "__main__"dalam file A menjadi salah, sehingga ia mencetak Anda tidak dapat melihat saya

b

Nikil Munireddy
sumber
5

Semua jawaban sudah cukup menjelaskan fungsionalitasnya. Tetapi saya akan memberikan satu contoh penggunaannya yang mungkin membantu membersihkan konsep lebih lanjut.

Asumsikan bahwa Anda memiliki dua file Python, a.py dan b.py. Sekarang, a.py mengimpor b.py. Kami menjalankan file a.py, tempat kode "import b.py" dijalankan terlebih dahulu. Sebelum sisa kode a.py berjalan, kode dalam file b.py harus berjalan sepenuhnya.

Dalam kode b.py ada beberapa kode yang eksklusif untuk file b.py dan kami tidak ingin file lain (selain file b.py), yang telah mengimpor file b.py, untuk menjalankannya.

Jadi itulah yang diperiksa oleh baris kode ini. Jika itu adalah file utama (yaitu, b.py) yang menjalankan kode, yang dalam hal ini bukan (a.py adalah file utama yang berjalan), maka hanya kode yang dieksekusi.

preetika mondal
sumber
4

Buat file, a.py :

print(__name__) # It will print out __main__

__name__selalu sama dengan __main__setiap kali file itu dijalankan secara langsung menunjukkan bahwa ini adalah file utama.

Buat file lain, b.py , di direktori yang sama:

import a  # Prints a

Menjalankannya. Ini akan mencetak sebuah , yaitu, nama file yang diimpor .

Jadi, untuk menunjukkan dua perilaku berbeda dari file yang sama , ini adalah trik yang umum digunakan:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly
DARK_C0D3R
sumber
4

jika nama == ' utama ':

Kami melihat apakah __name__ == '__main__': cukup sering.

Ia memeriksa apakah suatu modul sedang diimpor atau tidak.

Dengan kata lain, kode di dalam ifblok akan dieksekusi hanya ketika kode dijalankan secara langsung. Di sini directlyberartinot imported .

Mari kita lihat apa fungsinya menggunakan kode sederhana yang mencetak nama modul:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Jika kami menjalankan kode secara langsung melalui python test.py, nama modul adalah __main__:

call test()
test module name=__main__
Ali Hallaji
sumber
4

Sederhananya, ini adalah titik masuk untuk menjalankan file, seperti mainfungsi dalam bahasa pemrograman C.

Mohammed Awney
sumber
8
Jawaban ini membuat asumsi bahwa OP (atau pengguna mana pun dengan pertanyaan serupa) akrab dengan C dan tahu apa itu titik masuk.
arredond
1
Jawaban ini juga mengasumsikan bahwa tidak ada kode (selain definisi tanpa efek samping) yang terjadi sebelum if __name__ == "__main__"blok. Secara teknis, bagian atas skrip yang dieksekusi adalah titik masuk program.
Charlie Harding