-म स्विच का उद्देश्य क्या है?


174

क्या आप मुझे समझा सकते हैं कि कॉलिंग में क्या अंतर है

python -m mymod1 mymod2.py args

तथा

python mymod1.py mymod2.py args

ऐसा लगता है कि दोनों मामलों mymod1.pyमें कहा जाता है और sys.argvहै

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

तो -mस्विच के लिए क्या है ?


कृपया मुझे सही करें यदि मैं गलत हूं, लेकिन डिफ़ॉल्ट लाइब्रेरी पथ के -mलिए खोज करना लगता है mymod1। उदाहरण: python -m SimpleHTTPServerकाम करता है, जबकि python SimpleHTTPServerसाथ विफल रहता है can't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
बसज

7
मुझे वास्तव में यहाँ उत्तर स्पष्ट मिला: stackoverflow.com/questions/46319694/…
केसबेश

जवाबों:


137

PEP 338 के Rationaleअनुभाग की पहली पंक्ति कहती है:

पायथन 2.4 स्क्रिप्ट के रूप में निष्पादन के लिए पायथन मॉड्यूल नेमस्पेस का उपयोग करके मॉड्यूल को अनुमति देने के लिए कमांड लाइन स्विच -m जोड़ता है। प्रेरक उदाहरण मानक पुस्तकालय मॉड्यूल जैसे पीडीबी और प्रोफाइल थे, और पायथन 2.4 कार्यान्वयन इस सीमित उद्देश्य के लिए ठीक है।

तो आप पायथन के खोज पथ में किसी भी मॉड्यूल को इस तरह निर्दिष्ट कर सकते हैं, न कि केवल वर्तमान निर्देशिका में फ़ाइलें। आप ठीक कह रहे हैं कि python mymod1.py mymod2.py argsइसका ठीक वैसा ही प्रभाव है। Scope of this proposalअनुभाग की पहली पंक्ति बताती है:

पायथन 2.4 में, एम का उपयोग कर स्थित एक मॉड्यूल को ठीक उसी तरह निष्पादित किया जाता है जैसे कि उसका फ़ाइल नाम कमांड लाइन पर प्रदान किया गया था।

साथ -mअधिक मॉड्यूल जो एक पैकेज का हिस्सा हैं, आदि पीईपी 338 के बाकी के बारे में है के क्या यही कारण है कि के साथ काम करने की तरह संभव है। अधिक जानकारी के लिए इसे पढ़ें।


47
मेरा पसंदीदा उपयोग -mहै python -m SimpleHTTPServer। वास्तव में उपयोगी जब मुझे USB फ्लैश ड्राइव का उपयोग किए बिना कुछ फ़ाइलों को साझा करने की आवश्यकता होती है।
arifwn

21
@arifwn रनिंग पायथन 3 को थोड़े अपडेट की आवश्यकता है python -m http.serverऔर यह अभी भी बहुत बढ़िया है!
किट रोह

12
TL; DR: 1) आप चला सकते हैं python -m package.subpackage.moduleऔर सामान्य हल करने वाली मशीनरी का उपयोग किया जाएगा, आपको सटीक .pyफ़ाइल को इंगित करने की आवश्यकता नहीं है । 2) यह मॉड्यूल से रिश्तेदार आयात करने के लिए संभव है, जो बिना किसी वर्कआर्डर के चलाया जाता है, क्योंकि इसका पैकेज रास्ते में लोड किया जाएगा। 3) निरपेक्ष आयात आपके वर्तमान निर्देशिका पर आधारित होगा, न कि उस निर्देशिका में जहां .pyफ़ाइल है ( ''हेड के सिर पर है sys.path, बजाए इसके /path/to/my, यदि स्क्रिप्ट है /path/to/my/script.py)।
क्लैक

यह उत्तर क्या स्पष्ट नहीं करता है, यह केवल उन मॉड्यूल के सबसेट पर काम करता है जो निष्पादन योग्य होते हैं अर्थात एक __main__.pyफ़ाइल होती है। सबसे अधिक नहीं है और जैसे टूट जाएगा के python -m sys 'print(sys.version)'साथ विफल रहता है python: No code object available for sys। सुझाव दें कि उत्तर में स्पष्ट करें।
एसएमसीआई

19

यह ध्यान देने योग्य है कि यह केवल तभी काम करता है जब पैकेज में फ़ाइल है__main__.py अन्यथा, इस पैकेज को सीधे निष्पादित नहीं किया जा सकता है।

python -m some_package some_arguments

अजगर दुभाषिया __main__.pyनिष्पादित करने के लिए पैकेज पथ में एक फ़ाइल की तलाश करेगा । यह इसके बराबर है:

python path_to_package/__main__.py somearguments

यह सामग्री को निष्पादित करेगा:

if __name__ == "__main__":

2
पैकेज इनिट फ़ाइल के बारे में क्या? मुख्य फ़ाइल की उपस्थिति में, इनिट को भी लागू किया जाएगा?
चर

@ परवरिश हाँ init .py को मुख्य से पहले मंगवाया जाएगा। खूंटी मंगवाई गई है
मार्क रकर

1

इस सवाल के बावजूद कई बार पूछा गया और जवाब दिया गया (जैसे, यहाँ , यहाँ , यहाँ , और यहाँ ) मेरी राय में कोई मौजूदा जवाब पूरी तरह से या छिपकर -mध्वज के सभी निहितार्थों को नहीं पकड़ता है । इसलिए, जो पहले आया है उस पर सुधार करने का प्रयास करेगा।

परिचय (TLDR)

-mआदेश उन सभी नहीं बहुत कुछ जरूरी हर समय की आवश्यकता होगी है। संक्षेप में: (1) अजगर लिपियों को फाइलनाम (2) के बजाय मोडुलनेम के माध्यम से निष्पादित करने की अनुमति देता है (2) किसी को रिज़ॉल्यूशन के लिए जोड़ने के sys.pathलिए निर्देशिका चुनने की अनुमति देता है importऔर (3) पायथन स्क्रिप्ट को कमांड लाइन से निष्पादित करने के लिए सापेक्ष आयात की अनुमति देता है। ।

प्रारंभिक

-mध्वज को समझाने के लिए हमें पहले थोड़ी शब्दावली स्पष्ट करनी चाहिए।

सबसे पहले, पायथन की प्राथमिक संगठनात्मक इकाई को एक मॉड्यूल के रूप में जाना जाता है । मॉड्यूल दो फ्लेवर में आता है: कोड मॉड्यूल और पैकेज मॉड्यूल। एक कोड मॉड्यूल किसी भी फ़ाइल है जिसमें अजगर निष्पादन योग्य कोड होता है। एक पैकेज मॉड्यूल एक निर्देशिका है जिसमें अन्य मॉड्यूल (या तो कोड मॉड्यूल या पैकेज मॉड्यूल) होते हैं। सबसे सामान्य प्रकार के कोड मॉड्यूल *.pyफाइलें हैं जबकि सबसे सामान्य प्रकार के पैकेज मॉड्यूल निर्देशिकाएं हैं जिनमें __init__.pyफ़ाइल होती है।

दूसरा, सभी मॉड्यूल को विशिष्ट रूप से दो अलग-अलग तरीकों से पहचाना जा सकता है: <modulename>और <filename>। मॉड्यूल अक्सर पायथन कोड (जैसे, import <modulename>) में modulename और कमांड लाइन (जैसे, python <filename>) पर फ़ाइल नाम से पहचाने जाते हैं । सभी पायथन दुभाषिए मॉडुलेनाम को अच्छी तरह से परिभाषित नियमों के एक सेट के माध्यम से फ़ाइल नाम में बदल सकते हैं। ये नियम sys.pathचर पर टिका होता है और इसलिए इस मान को बदलकर मैपिंग को बदला जा सकता है (अधिक जानकारी के लिए यह पीईपी 302 कैसे देखा जाता है )।

तीसरा, सभी मॉड्यूल (कोड और पैकेज दोनों) निष्पादित किए जा सकते हैं (जिसके द्वारा हम मॉड्यूल से जुड़े कोड का अर्थ पायथन इंटरप्रेटर द्वारा मूल्यांकन किया जाएगा)। निष्पादन विधि, और मॉड्यूल प्रकार के आधार पर, किस कोड का मूल्यांकन किया जाता है, और कब, काफी बदल सकता है। उदाहरण के लिए, यदि कोई पैकेज मॉड्यूल का निष्पादन करता है, तो python <filename>उसके <filename>/__init__.pyबाद मूल्यांकन किया जाएगा <filename>/__main__.py। दूसरी ओर, यदि कोई उसी पैकेज मॉड्यूल को निष्पादित करता है, import <modulename>तो केवल पैकेज __init__.pyनिष्पादित किए जाएंगे।

का ऐतिहासिक विकास -m

सबसे पहले झंडे को पायथन 2.4.1 में पेश किया गया था । प्रारंभ में इसका एकमात्र उद्देश्य एक निष्पादन मॉड्यूल को निष्पादित करने के लिए वैकल्पिक साधन प्रदान करना था। यही है, अगर हम एक मॉड्यूल के लिए दोनों <filename>और जानते थे <modulename>तो निम्नलिखित दो कमांड बराबर थे: python <filename> <args>और python -m <modulename> <args>। इसके अतिरिक्त, PEP 338 के अनुसार -mकेवल इस पुनरावृत्ति ने शीर्ष स्तर के मॉडुलेनेम्स के साथ काम किया (यानी, ऐसे मॉड्यूल जो बिना किसी हस्तक्षेप के सीधे sys.path पर पाए जा सकते हैं)।

के पूरा होने के साथ पीईपी 338-m कार्यक्षमता समर्थन करने के लिए बढ़ाया गया था <modulename>शीर्ष स्तर modulenames परे अभ्यावेदन। इसका मतलब ऐसे नाम http.serverथे जो अब पूरी तरह से समर्थित थे। इस वृद्धि का मतलब यह भी था कि मॉड्यूल में सभी पैकेज अब लोड किए गए थे (यानी, सभी पैकेज __init__.pyफ़ाइलों का मूल्यांकन किया गया था), मॉड्यूल के साथ ही।

पीईपी 366 के लिए अंतिम प्रमुख फीचर एन्हांसमेंट -mआया । इस अद्यतन के साथ न केवल पूर्ण आयात बल्कि स्पष्ट सापेक्ष आयात का समर्थन करने की क्षमता प्राप्त हुई। यह कमांड में नामित मॉड्यूल के लिए चर को संशोधित करके हासिल किया गया था ।-m__package__-m

बक्सों का इस्तेमाल करें

-M ध्वज के लिए दो उल्लेखनीय उपयोग के मामले हैं:

  1. कमांड लाइन से मॉड्यूल निष्पादित करने के लिए जिसके लिए किसी को अपना फ़ाइल नाम नहीं पता हो सकता है। यह उपयोग मामला इस तथ्य का लाभ उठाता है कि पायथन दुभाषिया जानता है कि मॉडुलेनेम को फ़ाइल नाम में कैसे बदलना है। यह विशेष रूप से फायदेमंद होता है जब कोई कमांड लाइन से stdlib मॉड्यूल या 3-पार्टी मॉड्यूल चलाना चाहता है। उदाहरण के लिए, बहुत कम लोग http.serverमॉड्यूल के लिए फ़ाइल नाम जानते हैं, लेकिन ज्यादातर लोग इसके मॉड्यूलनाम को जानते हैं इसलिए हम कमांड लाइन का उपयोग करके इसे निष्पादित कर सकते हैं python -m http.server

  2. इसे स्थापित करने की आवश्यकता के बिना पूर्ण आयात वाले स्थानीय पैकेज को निष्पादित करने के लिए। यह उपयोग मामला PEP 338 में विस्तृत है और इस तथ्य का लाभ उठाता है कि वर्तमान कार्यशील निर्देशिका को sys.pathमॉड्यूल की निर्देशिका के बजाय जोड़ा गया है । यह उपयोग मामला pip install -e .विकसित / संपादन मोड में एक पैकेज को स्थापित करने के लिए उपयोग करने के समान है।

कमियों

-mवर्षों से किए गए सभी संवर्द्धन के साथ इसमें अभी भी एक बड़ी कमी है - यह केवल अजगर (यानी, * .py) में लिखे कोड मॉड्यूल को निष्पादित कर सकता है। उदाहरण के लिए, यदि -mC C संकलित कोड मॉड्यूल निष्पादित करने के लिए उपयोग किया जाता है तो निम्न त्रुटि उत्पन्न होगी, No code object available for <modulename>( अधिक विवरण के लिए यहां देखें)।

विस्तृत तुलना

अजगर आदेश के माध्यम से मॉड्यूल निष्पादन के प्रभाव (यानी, python <filename>):

  • sys.path में अंतिम निर्देशिका को शामिल करने के लिए संशोधित किया गया है <filename>
  • __name__ इस पर लगा है '__main__'
  • __package__ इस पर लगा है None
  • __init__.py किसी भी पैकेज के लिए मूल्यांकन नहीं किया जाता है (पैकेज मॉड्यूल के लिए स्वयं सहित)
  • __main__.pyपैकेज मॉड्यूल के लिए मूल्यांकन किया जाता है; कोड का मूल्यांकन कोड मॉड्यूल के लिए किया जाता है।

आयात विवरण (यानी, import <modulename>) के माध्यम से मॉड्यूल निष्पादन के प्रभाव :

  • sys.pathहै नहीं किसी भी तरह से संशोधित
  • __name__ के निरपेक्ष रूप पर सेट है <modulename>
  • __package__ में तत्काल मूल पैकेज पर सेट किया गया है <modulename>
  • __init__.py सभी पैकेजों के लिए मूल्यांकन किया जाता है (पैकेज मॉड्यूल के लिए स्वयं सहित)
  • __main__.pyपैकेज मॉड्यूल के लिए मूल्यांकन नहीं किया जाता है ; कोड का मूल्यांकन कोड मॉड्यूल के लिए किया जाता है

-M ध्वज के माध्यम से मॉड्यूल निष्पादन के प्रभाव (यानी, python -m <modulename>):

  • sys.path वर्तमान निर्देशिका को शामिल करने के लिए संशोधित किया गया है
  • __name__ इस पर लगा है '__main__'
  • __package__ में तत्काल मूल पैकेज पर सेट किया गया है <modulename>
  • __init__.py सभी पैकेजों के लिए मूल्यांकन किया जाता है (पैकेज मॉड्यूल के लिए स्वयं सहित)
  • __main__.pyपैकेज मॉड्यूल के लिए मूल्यांकन किया जाता है; कोड का मूल्यांकन कोड मॉड्यूल के लिए किया जाता है

निष्कर्ष

यह -mध्वज अपने सरलतम तरीके से, फिल्नाम के बजाय मॉडुलेनाम का उपयोग करके कमांड लाइन से अजगर लिपियों को निष्पादित करने का साधन है। इसके अतिरिक्त, -mअतिरिक्त कार्यक्षमता प्रदान करता है जो कि पाइथन कमांड लाइन की सुविधा के साथ importबयानों की शक्ति (जैसे, स्पष्ट सापेक्ष आयात और स्वत: पैकेज __init__मूल्यांकन के लिए समर्थन) को जोड़ती है ।


क्या आप python -m packagenameयहां बताए अनुसार उपयोग करने वाले पैकेज का उपयोग भी जोड़ सकते हैं: stackoverflow.com/a/53772635/1779091
चर

@ अच्छा विचार, मैंने एक "केस का उपयोग करें" अनुभाग जोड़ा, जिसमें वह भी शामिल है।
मार्क रूकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.