-M anahtarının amacı nedir?


174

Bana arama arasındaki farkın ne olduğunu açıklayabilir misiniz?

python -m mymod1 mymod2.py args

ve

python mymod1.py mymod2.py args

Her iki durumda da görünüyor mymod1.pydenir ve sys.argvolduğu

['mymod1.py', 'mymod2.py', 'args']

Peki -manahtar ne için?


Yanılıyorsam lütfen beni düzelt, ancak varsayılan kütüphane yolunda -marama yapıyor gibi görünüyor mymod1. Örnek: python -m SimpleHTTPServerçalışır, python SimpleHTTPServerbaşarısız olur can't open file 'SimpleHTTPServer': [Errno 2] No such file or directory.
18'de Basj

7
Aslında cevabı burada daha net buldum: stackoverflow.com/questions/46319694/…
Casebash

Yanıtlar:


137

PEP 338Rationale bölümünün ilk satırı şöyle diyor:

Python 2.4, komut dosyası olarak yürütmek üzere Python modülü ad alanı kullanılarak modüllerin bulunmasına izin vermek için -m komut satırı anahtarını ekler. Motive edici örnekler pdb ve profil gibi standart kütüphane modülleridir ve Python 2.4 uygulaması bu sınırlı amaç için uygundur.

Böylece Python'un arama yolundaki herhangi bir modülü sadece geçerli dizindeki dosyaları değil, bu şekilde belirleyebilirsiniz. python mymod1.py mymod2.py argsTam olarak aynı etkiye sahip olan doğru . Bölümün ilk satırında Scope of this proposalşunlar bulunur:

Python 2.4'te, -m kullanılarak bulunan bir modül, dosya adı komut satırında sağlanmış gibi yürütülür.

İle -mdaha PEP 338 geri kalanı hakkında en neyi O vs. bir paketin parçası olan modülleri ile çalışmak gibi, mümkündür. Daha fazla bilgi için okuyun.


47
Benim favori kullanım -molduğunu python -m SimpleHTTPServer. Bir usb flash sürücü kullanmadan bazı dosyaları paylaşmam gerektiğinde gerçekten kullanışlı.
arifwn

21
@arifwn Python3'ü çalıştırmak için hafif bir güncelleme gerekiyor python -m http.serverve bu hala harika!
Kit Roed

12
TL; DR: 1) Çalıştırabilir python -m package.subpackage.moduleve normal çözme makineleri kullanılacaktır, tam .pydosyayı belirtmeniz gerekmez . 2) Çalıştırılan modülden, herhangi bir geçici çözüm olmadan göreli ithalat yapmak mümkündür, çünkü paketi yol boyunca yüklenecektir. 3) Mutlak içe aktarmalar, .pydosyanın bulunduğu dizine değil, geçerli dizininize dayalı olacaktır ( komut dosyasının açık olması yerine ''başındadır ). sys.path/path/to/my/path/to/my/script.py
clacke

Bu cevabın açıklığa kavuşmadığı şey, bu sadece çalıştırılabilir olan modüllerin alt kümesinde çalışır, yani bir __main__.pydosyaya sahiptir. Çoğu kırılmaz ve kırılır, örneğin python -m sys 'print(sys.version)'başarısız olur python: No code object available for sys. Cevabı açıkça belirtmenizi öneririz.
smci

19

Bunun yalnızca paketin bir dosyası varsa işe yaradığını__main__.py belirtmek gerekir Aksi takdirde, bu paket doğrudan yürütülemez.

python -m some_package some_arguments

Python yorumlayıcısı __main__.pyyürütmek için paket yolunda bir dosya arayacaktır . Şuna eşittir:

python path_to_package/__main__.py somearguments

Aşağıdakilerden sonra içeriği yürütür:

if __name__ == "__main__":

2
Paket init dosyası ne olacak? Ana dosyanın varlığında init de çağrılır mı?
değişken

@variable Yes init .py, ana .py çağrılmadan önce çağrılır
Mark Rucker

1

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)

-mKomut 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.pathiç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 -mBayrağı ö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 *.pydosyalardı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.pathdeğ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__.pyzaman değerlendirilir <filename>/__main__.py. Öte yandan, eğer aynı paket modülünü yürütürse, import <modulename>sadece paketler __init__.pyyü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 -msadece ü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__.pymodü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:

  1. 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.servermodü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.

  2. 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.pathmodü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

-mYı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, -mC 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__.pypaket 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.patholduğ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__.pyolduğ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__.pypaket modülleri için değerlendirilir; kod, kod modülleri için değerlendirilir

Sonuç

-mBayrak 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 -mgü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 .


Ayrıca python -m packagenameburada belirtildiği şekilde kullanarak çağırma paketinin kullanımını da ekleyebilir misiniz : stackoverflow.com/a/53772635/1779091
değişken

@variable good idea, bunu içeren bir "Use Case" bölümü ekledim.
Mark Rucker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.