Mengapa Python menjalankan modul saya ketika saya mengimpornya, dan bagaimana cara menghentikannya?

173

Saya memiliki program Python yang sedang saya bangun yang dapat dijalankan dengan salah satu dari 2 cara: yang pertama adalah memanggil "python main.py" yang meminta pengguna untuk input dengan cara yang ramah dan kemudian menjalankan input pengguna melalui program. Cara lain adalah memanggil "python batch.py -file- " yang akan melewati semua pengumpulan input yang ramah dan menjalankan seluruh input file melalui program dalam sekali jalan.

Masalahnya adalah ketika saya menjalankan "batch.py" ia mengimpor beberapa variabel / metode / etc dari "main.py", dan ketika menjalankan kode ini:

import main

pada baris pertama program, program langsung error karena mencoba menjalankan kode di "main.py".

Bagaimana saya bisa menghentikan Python dari menjalankan kode yang terdapat dalam modul "main" yang saya impor?

Dasmowenator
sumber

Jawaban:

251

Karena ini hanya bagaimana Python bekerja - kata kunci seperti classdan defyang tidak deklarasi . Sebaliknya, itu adalah pernyataan nyata yang dieksekusi. Jika tidak dieksekusi, modul Anda akan .. kosong :-)

Bagaimanapun, pendekatan idiomatik adalah:

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

Lihat Apa if __name__ == "__main__"untuk?

Itu memang membutuhkan kontrol sumber atas modul yang sedang importdiedit.

Selamat coding.


sumber
1
hanya untuk mengonfirmasi, komentar Anda "barang hanya berjalan ketika tidak dipanggil melalui 'impor' di sini" menyiratkan perintah yang akan ditulis di bawah main (), kan? Atau tidak masalah ??
Goldname
@Goldname Kode di dalam pernyataan if tidak akan dijalankan ketika diimpor, tetapi fungsi utama itu sendiri didefinisikan dan siap digunakan bahkan melalui impor. Modul ini hanya akan menjalankan fungsi utama saat dijalankan, dan tidak menjalankannya jika diimpor. Itu semua tergantung pada apa yang ingin Anda lakukan. Jika Anda tidak memerlukan perintah di dalam main di tempat lain, tentu saja tuliskan di dalam if. Tetapi bagi saya itu terlihat lebih rapi.
Felix
51

Karena cara kerja Python, perlu untuk menjalankan modul Anda ketika mengimpornya.

Agar kode dalam modul tidak dieksekusi ketika diimpor, tetapi hanya ketika dijalankan secara langsung, Anda dapat menjaganya dengan ini if:

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

Anda mungkin ingin meletakkan kode ini dalam suatu main()metode, sehingga Anda dapat mengeksekusi file secara langsung, atau mengimpor modul dan memanggil main(). Misalnya, anggap ini ada dalam file foo.py.

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

Program ini dapat dijalankan dengan pergi python foo.py, atau dari skrip Python lain:

import foo

...

foo.main()
Jeremy Banks
sumber
12

Use the if __name__ == '__main__'idiom - __name__adalah variabel khusus yang nilainya '__main__'jika modul dijalankan sebagai skrip, dan nama modul jika itu diimpor. Jadi, Anda akan melakukan sesuatu seperti

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

Sayangnya, kamu tidak. Itu adalah bagian dari cara sintaks impor bekerja dan penting untuk melakukannya - ingat defsebenarnya adalah sesuatu yang dieksekusi, jika Python tidak menjalankan impor, Anda akan, yah, terjebak tanpa fungsi.

Karena Anda mungkin memiliki akses ke file, Anda mungkin dapat melihat dan melihat apa yang menyebabkan kesalahan. Dimungkinkan untuk memodifikasi lingkungan Anda untuk mencegah kesalahan terjadi.

cwallenpoole
sumber
1
Sebagai catatan: jika tidak ada cara untuk mengubah lingkungan sehingga kesalahan dapat dicegah, mungkin Anda harus menggunakan modul yang berbeda
cwallenpoole
4

Masukkan kode di dalam fungsi dan itu tidak akan berjalan sampai Anda memanggil fungsi. Anda harus memiliki fungsi utama di main.py. dengan pernyataan:

if __name__ == '__main__':
  main()

Kemudian, jika Anda memanggil python main.pyyang main()fungsi akan berjalan. Jika Anda mengimpor main.py, itu tidak akan. Juga, Anda mungkin harus mengganti nama main.pymenjadi sesuatu yang lain demi kejelasan.

Mat
sumber
3

Ada proposal peningkatan Python PEP 299 yang bertujuan untuk mengganti if __name__ == '__main__':idiom dengan def __main__:, tetapi ditolak. Ini masih merupakan bacaan yang baik untuk mengetahui apa yang harus diingat ketika menggunakan if __name__ = '__main__':.

Paul Tobias
sumber
2

Anda dapat menulis "main.py" Anda seperti ini:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()
hgoldfish
sumber
-1

Meskipun Anda tidak dapat menggunakan importtanpa menjalankan kode; ada cara yang cukup cepat di mana Anda dapat memasukkan variabel Anda; dengan menggunakan numpy.savez, yang menyimpan variabel sebagai array numpy dalam file .npz. Setelah itu Anda dapat memuat variabel menggunakan numpy.load.

Lihat deskripsi lengkap dalam dokumentasi yang lemah

Harap dicatat ini hanya untuk variabel dan array variabel, dan bukan untuk metode, dll.

pengguna3569257
sumber
-4

Coba impor saja fungsi yang diperlukan dari main.py? Begitu,

from main import SomeFunction

Bisa jadi Anda telah menamai fungsi dalam batch.py ​​sama dengan yang ada di main.py, dan ketika Anda mengimpor main.py program menjalankan fungsi main.py alih-alih fungsi batch.py; melakukan hal di atas akan memperbaikinya. Saya harap.

Dave Lewis
sumber
Setidaknya di Windows, tidak.
Martín Coll
2
import mainTIDAK mengimpor semuanya dari main ke namespace saat ini. Itu hanya menambahkan satu mainsimbol di namespace saat ini, sehingga tabrakan tidak dapat terjadi.
remram