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 -m
bendera. Oleh karena itu, berikut ini akan berusaha untuk memperbaiki apa yang telah terjadi sebelumnya.
Pengantar (TLDR)
The -m
perintah 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.path
untukimport
resolusi dan (3) memungkinkan script python dengan impor relatif akan dieksekusi dari baris perintah .
Persiapan
Untuk menjelaskan -m
bendera, 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 *.py
paling 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.path
variabel 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__.py
akan dievaluasi diikuti oleh <filename>/__main__.py
. Di sisi lain, jika seseorang mengeksekusi modul paket yang sama via import <modulename>
maka hanya paket yang __init__.py
akan 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 -m
hanya bekerja dengan modulenames tingkat atas (yaitu, modul yang dapat ditemukan langsung di sys.path tanpa paket intervensi).
Dengan selesainya PEP 338 yang -m
fungsi diperpanjang dukungan <modulename>
representasi luar modulenames tingkat atas. Ini berarti nama-nama seperti http.server
sekarang sepenuhnya didukung. Peningkatan ini juga berarti bahwa semua paket dalam sebuah modul sekarang dimuat (yaitu, semua __init__.py
file paket dievaluasi), bersama dengan modul itu sendiri.
Peningkatan fitur utama akhir untuk -m
datang dengan PEP 366 . Dengan pembaruan ini -m
diperoleh kemampuan untuk mendukung tidak hanya impor absolut tetapi juga impor relatif eksplisit. Ini dicapai dengan memodifikasi __package__
variabel untuk modul bernama dalam -m
perintah.
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.server
modul 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.path
direktori 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 -m
selama bertahun-tahun masih memiliki satu kekurangan utama - itu hanya dapat menjalankan modul kode yang ditulis dengan python (yaitu, * .py). Misalnya, jika -m
digunakan 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__.py
dievaluasi untuk modul paket; kode dievaluasi untuk modul kode.
Efek dari eksekusi modul melalui pernyataan impor (yaitu, import <modulename>
):
sys.path
adalah 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__.py
adalah 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__.py
dievaluasi untuk modul paket; kode dievaluasi untuk modul kode
Kesimpulan
The -m
bendera, pada yang paling sederhana, alat untuk mengeksekusi script python dari baris perintah dengan menggunakan modulenames bukan nama file. Selain itu, -m
memberikan fungsionalitas tambahan yang menggabungkan kekuatan import
pernyataan (misalnya, dukungan untuk impor relatif eksplisit dan __init__
evaluasi paket otomatis ) dengan kenyamanan baris perintah python.
-m
tampaknya mencarimymod1
di jalur pustaka default. Contoh:python -m SimpleHTTPServer
berfungsi, sedangkanpython SimpleHTTPServer
gagal dengancan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
.