Meskipun pertanyaan ini telah ditanyakan dan dijawab beberapa kali (misalnya, di sini , di sini , di sini , dan di sini ) menurut pendapat saya tidak ada jawaban yang ada sepenuhnya atau secara ringkas menangkap semua implikasi dari -mbendera. Oleh karena itu, berikut ini akan berusaha untuk memperbaiki apa yang telah terjadi sebelumnya.
Pengantar (TLDR)
The -mperintah melakukan banyak hal tidak semua dari mereka akan selalu dibutuhkan setiap saat. Singkatnya: (1) memungkinkan skrip python dieksekusi melalui modulename daripada filename (2) memungkinkan seseorang untuk memilih direktori untuk ditambahkan ke sys.pathuntukimport resolusi dan (3) memungkinkan script python dengan impor relatif akan dieksekusi dari baris perintah .
Persiapan
Untuk menjelaskan -mbendera, pertama-tama kita harus memperjelas terminologi kecil.
Pertama, unit organisasi utama Python dikenal sebagai modul . Modul datang dalam salah satu dari dua rasa: modul kode dan modul paket. Modul kode adalah file apa pun yang berisi kode yang dapat dieksekusi python. Modul paket adalah direktori yang berisi modul lain (baik modul kode atau modul paket). Jenis modul kode yang *.pypaling umum adalah file sedangkan jenis modul paket yang paling umum adalah direktori yang berisi__init__.py file.
Kedua, semua modul dapat diidentifikasi secara unik dalam dua cara berbeda: <modulename>dan <filename>. Modul paling sering diidentifikasi oleh modulename dalam kode Python (misalnya, import <modulename>) dan dengan nama file pada baris perintah (misalnya, python <filename>). Semua juru bahasa Python dapat mengubah modulenames menjadi nama file melalui seperangkat aturan yang didefinisikan dengan baik. Aturan-aturan ini bergantung pada sys.pathvariabel dan karenanya pemetaan dapat diubah dengan mengubah nilai ini (untuk lebih lanjut tentang bagaimana hal ini dilakukan lihat PEP 302 ).
Ketiga, semua modul (baik kode dan paket) dapat dieksekusi (maksud kami kode yang terkait dengan modul akan dievaluasi oleh juru bahasa Python). Bergantung pada metode eksekusi, dan jenis modul, kode apa yang dievaluasi, dan kapan, dapat berubah sedikit. Sebagai contoh, jika seseorang mengeksekusi modul paket melalui python <filename>maka <filename>/__init__.pyakan dievaluasi diikuti oleh <filename>/__main__.py. Di sisi lain, jika seseorang mengeksekusi modul paket yang sama via import <modulename>maka hanya paket yang __init__.pyakan dieksekusi.
Perkembangan Sejarah -m
Bendera -m pertama kali diperkenalkan dalam Python 2.4.1 . Awalnya satu-satunya tujuan adalah untuk menyediakan cara alternatif untuk mengidentifikasi modul python untuk dieksekusi. Yaitu, jika kita tahu modul <filename>dan <modulename>untuk modul maka dua perintah berikut ini setara: python <filename> <args>dan python -m <modulename> <args>. Selain itu, menurut PEP 338 iterasi ini -mhanya bekerja dengan modulenames tingkat atas (yaitu, modul yang dapat ditemukan langsung di sys.path tanpa paket intervensi).
Dengan selesainya PEP 338 yang -mfungsi diperpanjang dukungan <modulename>representasi luar modulenames tingkat atas. Ini berarti nama-nama seperti http.serversekarang sepenuhnya didukung. Peningkatan ini juga berarti bahwa semua paket dalam sebuah modul sekarang dimuat (yaitu, semua __init__.pyfile paket dievaluasi), bersama dengan modul itu sendiri.
Peningkatan fitur utama akhir untuk -mdatang dengan PEP 366 . Dengan pembaruan ini -mdiperoleh kemampuan untuk mendukung tidak hanya impor absolut tetapi juga impor relatif eksplisit. Ini dicapai dengan memodifikasi __package__variabel untuk modul bernama dalam -mperintah.
Gunakan Kasing
Ada dua kasus penggunaan penting untuk flag -m:
Untuk menjalankan modul dari baris perintah yang orang mungkin tidak tahu nama file mereka. Use case ini mengambil keuntungan dari fakta bahwa interpreter Python tahu cara mengubah modulenames menjadi nama file. Ini sangat menguntungkan ketika seseorang ingin menjalankan modul stdlib atau modul pihak ke-3 dari baris perintah. Sebagai contoh, sangat sedikit orang yang tahu nama file untuk http.servermodul tetapi kebanyakan orang tahu modulename-nya sehingga kita dapat mengeksekusinya dari baris perintah dengan menggunakan python -m http.server.
Untuk menjalankan paket lokal yang mengandung impor absolut tanpa perlu menginstalnya. Kasus penggunaan ini dirinci dalam PEP 338 dan memanfaatkan fakta bahwa direktori kerja saat ini ditambahkan ke sys.pathdirektori modul. Kasus penggunaan ini sangat mirip dengan menggunakan pip install -e .untuk menginstal paket dalam mode mengembangkan / mengedit.
Kekurangan
Dengan semua perangkat tambahan yang dibuat -mselama bertahun-tahun masih memiliki satu kekurangan utama - itu hanya dapat menjalankan modul kode yang ditulis dengan python (yaitu, * .py). Misalnya, jika -mdigunakan untuk menjalankan modul kode yang dikompilasi C kesalahan berikut akan dihasilkan, No code object available for <modulename>(lihat di sini untuk detail lebih lanjut).
Perbandingan terperinci
Efek dari eksekusi modul melalui perintah python (yaitu, python <filename>):
sys.path dimodifikasi untuk memasukkan direktori final di <filename>
__name__ diatur ke '__main__'
__package__ diatur ke None
__init__.py tidak dievaluasi untuk paket apa pun (termasuk paket modulnya sendiri)
__main__.pydievaluasi untuk modul paket; kode dievaluasi untuk modul kode.
Efek dari eksekusi modul melalui pernyataan impor (yaitu, import <modulename>):
sys.pathadalah tidak diubah dengan cara apapun
__name__ diatur ke bentuk absolut dari <modulename>
__package__ diatur ke paket induk langsung di <modulename>
__init__.py dievaluasi untuk semua paket (termasuk sendiri untuk modul paket)
__main__.pyadalah tidak dievaluasi untuk modul paket; kode dievaluasi untuk modul kode
Efek dari eksekusi modul melalui flag -m (yaitu, python -m <modulename>):
sys.path dimodifikasi untuk memasukkan direktori saat ini
__name__ diatur ke '__main__'
__package__ diatur ke paket induk langsung di <modulename>
__init__.py dievaluasi untuk semua paket (termasuk sendiri untuk modul paket)
__main__.pydievaluasi untuk modul paket; kode dievaluasi untuk modul kode
Kesimpulan
The -mbendera, pada yang paling sederhana, alat untuk mengeksekusi script python dari baris perintah dengan menggunakan modulenames bukan nama file. Selain itu, -mmemberikan fungsionalitas tambahan yang menggabungkan kekuatan importpernyataan (misalnya, dukungan untuk impor relatif eksplisit dan __init__evaluasi paket otomatis ) dengan kenyamanan baris perintah python.
-mtampaknya mencarimymod1di jalur pustaka default. Contoh:python -m SimpleHTTPServerberfungsi, sedangkanpython SimpleHTTPServergagal dengancan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory.