Bu sorunun birkaç kez sorulmasına ve yanıtlanmasına rağmen (örneğin, burada , burada , burada ve burada ) bence hiçbir mevcut cevap, yanıtın tüm sonuçlarını tam veya kısaca yakalayamaz.-m
bayrağın . Bu nedenle, aşağıdakiler daha önce olanları geliştirmeye çalışacaktır.
Giriş (TLDR)
-m
Komut hepsi değil bir çok şey mutlaka her zaman ihtiyaç olacaktır yapar. Kısacası o: piton komut eklemek için bir dizin seçmek için bir modulename ziyade dosya (2) üzerinden yürütülecek verir edilecek için (1) verir sys.path
içinimport
çözünürlük ve (3) göreli ithalat ile piton komut komut satırından çalıştırılmasına izin verir .
Hazırlıklar
Açıklamak -m
Bayrağı önce küçük bir terminoloji ortaya koymalıyız.
İlk olarak, Python'un birincil organizasyon birimi bir modül olarak bilinir . Modüllerin iki çeşidi vardır: kod modülleri ve paket modülleri. Kod modülü, python yürütülebilir kodu içeren herhangi bir dosyadır. Paket modülü, diğer modülleri (kod modülleri veya paket modülleri) içeren bir dizindir. En yaygın kod modülleri *.py
dosyalardır, en yaygın paket modülleri ise__init__.py
dosya .
İkincisi, tüm modüller iki farklı şekilde benzersiz bir şekilde tanımlanabilir: <modulename>
ve <filename>
. Modüller çoğunlukla Python kodundaki modulename (örn. import <modulename>
) Ve komut satırındaki dosya adıyla (örn. ) Tanımlanır python <filename>
. Tüm Python yorumlayıcıları, iyi tanımlanmış bir dizi kural aracılığıyla modül adlarını dosya adlarına dönüştürebilir. Bu kurallar sys.path
değişkene bağlıdır ve bu nedenle eşleme bu değer değiştirilerek değiştirilebilir (bunun nasıl yapılacağı hakkında daha fazla bilgi için bkz. PEP 302 ).
Üçüncü olarak, tüm modüller (hem kod hem de paket) yürütülebilir (modülle ilişkili kodun Python yorumlayıcısı tarafından değerlendirileceği anlamına gelir). Yürütme yöntemine ve modül türüne bağlı olarak, hangi kod değerlendirilir ve ne zaman biraz değişebilir. Örneğin, biri bir paket modülünü yürütürse, python <filename>
o <filename>/__init__.py
zaman değerlendirilir <filename>/__main__.py
. Öte yandan, eğer aynı paket modülünü yürütürse, import <modulename>
sadece paketler __init__.py
yürütülür.
Tarihsel Gelişimi -m
-M bayrağı ilk olarak Python 2.4.1'de tanıtıldı . Başlangıçta tek amacı, yürütülecek bir python modülünü tanımlamak için alternatif bir yol sağlamaktı. İkimiz de bilse olduğunu, <filename>
ve <modulename>
bir modül için aşağıdaki iki komut eşdeğerdir: python <filename> <args>
ve python -m <modulename> <args>
. Ek olarak, PEP 338'e göre, bu yineleme -m
sadece üst düzey modül adları ile çalışmıştır (yani, herhangi bir müdahale paketi olmadan doğrudan sys.path üzerinde bulunabilen modüller).
Tamamlanmasıyla birlikte PEP 338-m
işlevselliği desteği için uzatıldı <modulename>
üst düzey modulenames ötesinde temsiller. Bu http.server
, artık tam olarak desteklenen gibi adlar anlamına geliyordu . Bu geliştirme ayrıca bir modüldeki tüm paketlerin __init__.py
modülün kendisiyle birlikte yüklendiği (yani tüm paket dosyalarının değerlendirildiği) anlamına geliyordu .
Son büyük özellik geliştirmesi PEP 366-m
ile geldi . Bu güncellemeyle sadece mutlak ithalatı değil, aynı zamanda açık göreli ithalatı da destekleme yeteneği kazanıldı. Bu, komuttaki adlandırılmış modül için değişken değiştirilerek başarıldı .-m
__package__
-m
Kullanım Örnekleri
-M bayrağı için iki önemli kullanım durumu vardır:
Dosya adlarını bilmeyen komut satırından modülleri yürütmek için. Bu kullanım durumu, Python yorumlayıcısının modül adlarını dosya adlarına nasıl dönüştüreceğini bilmesi gerçeğinden yararlanır. Bu, özellikle komut satırından stdlib modüllerini veya 3. taraf modülünü çalıştırmak istediğinde avantajlıdır. Örneğin, çok az kişi http.server
modülün dosya adını bilir, ancak çoğu kişi modül adını bilir, böylece komut satırını kullanarak komut satırını yürütebiliriz python -m http.server
.
Yüklemeye gerek kalmadan mutlak ithalat içeren bir yerel paket yürütmek. Bu kullanım durumu PEP 338'de ayrıntılı olarak açıklanmaktadır ve geçerli çalışma dizininin sys.path
modül dizini yerine eklenmesi gerçeğinden yararlanmaktadır . Bu kullanım durumu, pip install -e .
bir paketi geliştirme / düzenleme modunda yüklemek için kullanılmaya çok benzer .
eksiklikleri
-m
Yıllar boyunca yapılan tüm geliştirmelerle birlikte hala büyük bir eksikliği var - sadece python ile yazılmış kod modüllerini yürütebilir (yani, * .py). Örneğin, -m
C derlenmiş kod modülünü yürütmek için kullanılırsa, aşağıdaki hata üretilir No code object available for <modulename>
( daha fazla ayrıntı için buraya bakın).
Detaylı Karşılaştırmalar
Python komutu ile modül yürütmenin etkileri (örn. python <filename>
):
sys.path
içindeki son dizini içerecek şekilde değiştirildi <filename>
__name__
ayarlandı '__main__'
__package__
ayarlandı None
__init__.py
herhangi bir paket için değerlendirilmez (paket modülleri için kendi paketi dahil)
__main__.py
paket modülleri için değerlendirilir; kod, kod modülleri için değerlendirilir.
Modül yürütmenin import deyimi (yani import <modulename>
) ile etkileri :
sys.path
olduğu değil herhangi bir şekilde modifiye
__name__
mutlak biçimine ayarlanır <modulename>
__package__
içindeki üst paket olarak ayarlandı <modulename>
__init__.py
tüm paketler için değerlendirilir (paket modülleri için kendi paketleri dahil)
__main__.py
olduğu değil paket modülleri için değerlendirilir; kod, kod modülleri için değerlendirilir
-M bayrağı (örn. python -m <modulename>
) İle modül yürütülmesinin etkileri :
sys.path
geçerli dizini içerecek şekilde değiştirildi
__name__
ayarlandı '__main__'
__package__
içindeki üst paket olarak ayarlandı <modulename>
__init__.py
tüm paketler için değerlendirilir (paket modülleri için kendi paketleri dahil)
__main__.py
paket modülleri için değerlendirilir; kod, kod modülleri için değerlendirilir
Sonuç
-m
Bayrak en basit, modulenames yerine dosya adlarını kullanarak komut satırından piton komut dosyalarını yürütmek için bir araç olarak vardır. Ek olarak, ifadelerin -m
gücünü import
(örneğin, açık göreli ithalat ve otomatik paket __init__
değerlendirmesi için destek ) python komut satırının rahatlığıyla birleştiren ek işlevler sağlar .
-m
arama yapıyor gibi görünüyormymod1
. Örnek:python -m SimpleHTTPServer
çalışır,python SimpleHTTPServer
başarısız olurcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
.