Bisakah Anda menjelaskan kepada saya apa perbedaan antara menelepon
python -m mymod1 mymod2.py args
dan
python mymod1.py mymod2.py args
Tampaknya dalam kedua kasus mymod1.py
disebut dan sys.argv
merupakan
['mymod1.py', 'mymod2.py', 'args']
Jadi untuk apa -m
saklar itu?
python
command-line
module
package
Charles Brunet
sumber
sumber
-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
.Jawaban:
Baris pertama dari
Rationale
bagian PEP 338 mengatakan:Jadi Anda dapat menentukan modul apa pun di jalur pencarian Python dengan cara ini, bukan hanya file di direktori saat ini. Anda benar yang
python mymod1.py mymod2.py args
memiliki efek yang persis sama. Baris pertamaScope of this proposal
menyatakan bagian:Dengan
-m
lebih banyak dimungkinkan, seperti bekerja dengan modul yang merupakan bagian dari paket, dll. Itulah inti dari PEP 338. Baca untuk info lebih lanjut.sumber
-m
adalahpython -m SimpleHTTPServer
. Sangat praktis ketika saya perlu berbagi beberapa file tanpa menggunakan usb flash drive.python -m http.server
dan ini masih mengagumkan!python -m package.subpackage.module
dan mesin penyelesaian normal akan digunakan, Anda tidak perlu menunjukkan.py
file yang tepat . 2) Dimungkinkan untuk melakukan impor relatif dari modul yang dijalankan, tanpa penyelesaian, karena paketnya akan dimuat di sepanjang jalan. 3) Impor absolut akan didasarkan pada direktori Anda saat ini, bukan direktori tempat.py
file berada (''
berada di kepalasys.path
, bukan/path/to/my
, jika skrip berada di/path/to/my/script.py
).__main__.py
file. Sebagian besar tidak dan akan rusak misalnyapython -m sys 'print(sys.version)'
gagalpython: No code object available for sys
. Sarankan Anda menjelaskannya dalam jawaban.Layak disebutkan ini hanya berfungsi jika paket memiliki file.
__main__.py
Jika tidak, paket ini tidak dapat dieksekusi secara langsung.Penerjemah python akan mencari
__main__.py
file di jalur paket untuk dieksekusi. Ini setara dengan:Ini akan mengeksekusi konten setelah:
sumber
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 kesys.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 padasys.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 viaimport <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>
danpython -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 sepertihttp.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 menggunakanpython -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 menggunakanpip 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 keNone
__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 kodeEfek 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 kodeKesimpulan
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 kekuatanimport
pernyataan (misalnya, dukungan untuk impor relatif eksplisit dan__init__
evaluasi paket otomatis ) dengan kenyamanan baris perintah python.sumber
python -m packagename
seperti yang disebutkan di sini: stackoverflow.com/a/53772635/1779091