Eksekusi kode Python dengan opsi -m atau tidak
Gunakan -m
benderanya.
Hasilnya hampir sama ketika Anda memiliki skrip, tetapi ketika Anda mengembangkan sebuah paket, tanpa -m
flag, tidak ada cara untuk membuat impor bekerja dengan benar jika Anda ingin menjalankan sub-paket atau modul dalam paket sebagai entri utama arahkan ke program Anda (dan percayalah, saya sudah mencoba.)
Dokumen
Seperti dokumen di bendera -m yang mengatakan:
Cari sys.path untuk modul bernama dan jalankan isinya sebagai __main__
modul.
dan
Seperti opsi -c, direktori saat ini akan ditambahkan ke awal sys.path.
begitu
python -m pdb
kira-kira setara dengan
python /usr/lib/python3.5/pdb.py
(dengan asumsi Anda tidak memiliki paket atau skrip di direktori Anda saat ini yang disebut pdb.py)
Penjelasan:
Perilaku dibuat "dengan sengaja mirip" dengan skrip.
Banyak modul pustaka standar berisi kode yang dipanggil saat dieksekusi sebagai skrip. Contohnya adalah modul timeit:
Beberapa kode python dimaksudkan untuk dijalankan sebagai modul: (Saya pikir contoh ini lebih baik daripada contoh doc opsi baris perintah)
$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 33.4 usec per loop
$ python -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 25.2 usec per loop
Dan dari sorotan catatan rilis untuk Python 2.4 :
Opsi baris perintah -m - python -m modulename akan menemukan modul di pustaka standar, dan memanggilnya. Misalnya, python -m pdb
setara denganpython /usr/lib/python2.4/pdb.py
Pertanyaan lanjutan
Juga, Referensi Esensial Python David Beazley menjelaskannya sebagai "Opsi -m menjalankan modul perpustakaan sebagai skrip yang dijalankan di dalam __main__
modul sebelum eksekusi skrip utama".
Artinya, setiap modul yang dapat Anda cari dengan pernyataan impor dapat dijalankan sebagai titik masuk program - jika memiliki blok kode, biasanya di dekat akhir, dengan if __name__ == '__main__':
.
-m
tanpa menambahkan direktori saat ini ke jalur:
Sebuah komentar di sini di tempat lain mengatakan:
Bahwa opsi -m juga menambahkan direktori saat ini ke sys.path, jelas merupakan masalah keamanan (lihat: serangan preload). Perilaku ini mirip dengan urutan pencarian perpustakaan di Windows (sebelum dikeraskan baru-baru ini). Sayangnya Python tidak mengikuti tren dan tidak menawarkan cara sederhana untuk menonaktifkan penambahan. ke sys.path
Nah, ini menunjukkan kemungkinan masalah - (di windows hapus tanda kutip):
echo "import sys; print(sys.version)" > pdb.py
python -m pdb
3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Gunakan -I
tanda tersebut untuk menguncinya untuk lingkungan produksi (baru di versi 3.4):
python -Im pdb
usage: pdb.py [-c command] ... pyfile [arg] ...
etc...
dari dokumen :
-I
Jalankan Python dalam mode terisolasi. Ini juga menyiratkan -E dan -s. Dalam mode terisolasi, sys.path tidak berisi direktori skrip maupun direktori paket situs pengguna. Semua variabel lingkungan PYTHON * juga diabaikan. Pembatasan lebih lanjut dapat diberlakukan untuk mencegah pengguna memasukkan kode berbahaya.
Apa yang __package__
dilakukannya?
Ini memungkinkan impor relatif eksplisit, tidak terlalu terkait dengan pertanyaan ini, meskipun - lihat jawaban ini di sini: Apa tujuan dari atribut "__package__" di Python?
PYTHONPATH=test python -m foo.bar
? Bisakah Anda menjelaskannya secara detail?