python - क्या होता है यदि __name__ == "__main__": क्या करें?




13 Answers

जब आपकी स्क्रिप्ट पाइथन दुभाषिया को कमांड के रूप में पास करके चलाया जाता है,

python myscript.py

इंडेंटेशन स्तर 0 पर मौजूद सभी कोड निष्पादित हो जाते हैं। परिभाषित किए गए कार्यों और वर्गों को अच्छी तरह से परिभाषित किया गया है, लेकिन उनमें से कोई भी कोड चलाया नहीं जाता है। अन्य भाषाओं के विपरीत, कोई main() फ़ंक्शन नहीं है जो स्वचालित रूप से चलाया जाता है - main() फ़ंक्शन शीर्ष स्तर पर सभी कोड स्पष्ट रूप से होता है।

इस मामले में, शीर्ष-स्तर कोड एक ब्लॉक है। __name__ एक अंतर्निहित चर है जो वर्तमान मॉड्यूल के नाम पर मूल्यांकन करता है। हालांकि, यदि कोई मॉड्यूल सीधे चलाया जा रहा है (जैसा कि उपरोक्त myscript.py है), तो __name__ बजाय __name__ स्ट्रिंग "__main__" सेट है। इस प्रकार, आप परीक्षण कर सकते हैं कि आपकी स्क्रिप्ट को सीधे चलाया जा रहा है या परीक्षण करके किसी और द्वारा आयात किया जा रहा है या नहीं

if __name__ == "__main__":
    ...

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

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

अब, यदि आप दुभाषिया के रूप में आह्वान करते हैं

python one.py

आउटपुट होगा

top-level in one.py
one.py is being run directly

यदि आप इसके बजाय दो. two.py चलाते हैं:

python two.py

आपको मिला

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

इस प्रकार, जब मॉड्यूल लोड हो जाता है, तो इसका __name__ "__main__" बजाय "one" बराबर होता है।

python namespaces main python-module idioms

if __name__ == "__main__": तो क्या करें?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))



if __name__ == "__main__": तो क्या करें?

मूल बातें की रूपरेखा के लिए:

  • वैश्विक चर, __name__ , मॉड्यूल में जो आपके प्रोग्राम में प्रवेश बिंदु है, '__main__' । अन्यथा, यह वह नाम है जिसे आप मॉड्यूल आयात करते हैं।

  • इसलिए, if ब्लॉक के तहत कोड केवल तभी चलाया जाएगा जब मॉड्यूल आपके प्रोग्राम में प्रवेश बिंदु है।

  • यह आयात पर नीचे कोड ब्लॉक निष्पादित किए बिना, अन्य मॉड्यूल द्वारा मॉड्यूल में कोड आयात करने की अनुमति देता है।

हमें यह क्यों चाहिये?

अपने कोड का विकास और परीक्षण

मान लें कि आप मॉड्यूल के रूप में उपयोग किए जाने के लिए डिज़ाइन की गई एक पायथन लिपि लिख रहे हैं:

def do_important():
    """This function does something very important"""

आप फ़ंक्शन के इस कॉल को नीचे जोड़कर मॉड्यूल का परीक्षण कर सकते हैं :

do_important()

और इसे चलाने (कमांड प्रॉम्प्ट पर) कुछ ऐसा करने के साथ:

~$ python important.py

समस्या

हालांकि, यदि आप मॉड्यूल को किसी अन्य स्क्रिप्ट में आयात करना चाहते हैं:

import important

आयात पर, do_important फ़ंक्शन को कॉल किया जाएगा, इसलिए आप शायद नीचे अपने फ़ंक्शन कॉल, do_important() टिप्पणी करेंगे।

# do_important() # I must remember to uncomment to execute this!

और फिर आपको याद रखना होगा कि आपने अपनी टेस्ट फ़ंक्शन कॉल पर टिप्पणी की है या नहीं। और यह अतिरिक्त जटिलता का अर्थ यह होगा कि आप भूलने की संभावना रखते हैं, जिससे आपकी विकास प्रक्रिया अधिक परेशानी हो जाती है।

एक बेहतर तरीका

__name__ परिवर्तनीय बिंदु नामस्थान पर जहां भी पाइथन दुभाषिया इस समय होता है।

एक आयातित मॉड्यूल के अंदर, यह उस मॉड्यूल का नाम है।

लेकिन प्राथमिक मॉड्यूल (या एक इंटरैक्टिव पायथन सत्र, यानी दुभाषिया के पढ़ने, इवल, प्रिंट लूप, या आरईपीएल) के अंदर आप अपने "__main__" से सब कुछ चला रहे हैं।

तो यदि आप निष्पादन से पहले जांचते हैं:

if __name__ == "__main__":
    do_important()

उपर्युक्त के साथ, आपका कोड केवल तब लागू होगा जब आप इसे प्राथमिक मॉड्यूल के रूप में चला रहे हों (या जानबूझकर इसे किसी अन्य स्क्रिप्ट से कॉल करें)।

एक बेहतर तरीका भी

हालांकि, इस पर सुधार करने के लिए एक पाइथोनिक तरीका है।

क्या होगा यदि हम मॉड्यूल के बाहर से इस व्यवसाय प्रक्रिया को चलाने के लिए चाहते हैं?

अगर हम कोड डालते हैं तो हम व्यायाम करना चाहते हैं क्योंकि हम इस तरह के एक समारोह में विकसित और परीक्षण करते हैं और फिर तुरंत '__main__' लिए हमारी जांच करते हैं:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

अब हमारे मॉड्यूल के अंत के लिए एक अंतिम कार्य है जो हम मॉड्यूल को प्राथमिक मॉड्यूल के रूप में चलाने पर चलाएंगे।

यह मॉड्यूल और उसके कार्यों और वर्गों को main कार्य चलाने के बिना अन्य स्क्रिप्ट में आयात करने की अनुमति देगा, और एक अलग '__main__' मॉड्यूल से चलते समय मॉड्यूल (और इसके कार्यों और वर्गों) को कॉल करने की अनुमति भी देगा, यानी

import important
important.main()

यह मुहावरे __main__ मॉड्यूल की व्याख्या में पाइथन दस्तावेज़ में भी पाया जा सकता है। वह पाठ कहता है:

यह मॉड्यूल (अन्यथा अज्ञात) गुंजाइश का प्रतिनिधित्व करता है जिसमें दुभाषिया का मुख्य प्रोग्राम निष्पादित होता है - कमांड को मानक इनपुट से, स्क्रिप्ट फ़ाइल से, या एक इंटरैक्टिव प्रॉम्प्ट से पढ़ा जाता है। यह वह वातावरण है जिसमें मूर्खतापूर्ण "सशर्त स्क्रिप्ट" स्टांजा स्क्रिप्ट को चलाने का कारण बनती है:

if __name__ == '__main__':
    main()



क्या होता है if __name__ == "__main__": क्या करें?

__name__ एक वैश्विक चर है (पायथन में, वैश्विक वास्तव में मॉड्यूल स्तर पर है ) जो सभी नामस्थानों में मौजूद है। यह आमतौर पर मॉड्यूल का नाम होता है (एक str प्रकार के रूप में)।

हालांकि, एकमात्र विशेष मामला, हालांकि, जो भी पायथन प्रक्रिया आप चलाते हैं, जैसा कि mycode.py में है:

python mycode.py

अन्यथा अज्ञात वैश्विक नामस्थान को '__main__' के मान को '__main__' असाइन किया गया है।

इस प्रकार, अंतिम लाइनों सहित

if __name__ == '__main__':
    main()
  • अपनी mycode.py स्क्रिप्ट के अंत में,
  • जब यह प्राथमिक, एंट्री-पॉइंट मॉड्यूल होता है जो पाइथन प्रक्रिया द्वारा चलाया जाता है,

आपके स्क्रिप्ट के विशिष्ट रूप से परिभाषित main फ़ंक्शन को चलाने के लिए कारण बन जाएगा।

इस निर्माण का उपयोग करने का एक अन्य लाभ: आप अपने कोड को किसी अन्य स्क्रिप्ट में मॉड्यूल के रूप में भी आयात कर सकते हैं और फिर जब आपका प्रोग्राम निर्णय लेता है तो मुख्य फ़ंक्शन चलाएं:

import mycode
# ... any amount of other code
mycode.main()



जब हमारे मॉड्यूल में कुछ कथन होते हैं ( M.py ) हम निष्पादित करना चाहते हैं जब यह मुख्य (आयात नहीं किया गया) के रूप में चल रहा है, तो हम ब्लॉक के तहत उन बयानों (परीक्षण-मामलों, प्रिंट स्टेटमेंट) को रख सकते हैं।

डिफ़ॉल्ट रूप से (जब मॉड्यूल मुख्य के रूप में चल रहा है, आयात नहीं किया जाता है) __name__ चर "__main__" सेट होता है, और जब इसे आयात किया जाएगा तो __name__ चर को एक अलग मान मिलेगा, संभवतः मॉड्यूल का नाम ( 'M' )। यह एक मॉड्यूल के विभिन्न रूपों को एक साथ चलाने में मदद करता है, और उनके विशिष्ट इनपुट और आउटपुट स्टेटमेंट को अलग करता है और यदि कोई टेस्ट-केस भी होता है।

संक्षेप में , मॉड्यूल आयात होने पर (निश्चित) कोड को चलाने से रोकने के लिए इस ' if __name__ == "main" ' ब्लॉक का उपयोग करें।




बस रखें, __name__ प्रत्येक स्क्रिप्ट के लिए परिभाषित एक चर है जो परिभाषित करता है कि स्क्रिप्ट मुख्य मॉड्यूल के रूप में चल रही है या इसे आयातित मॉड्यूल के रूप में चलाया जा रहा है।

तो अगर हमारे पास दो स्क्रिप्ट हैं;

#script1.py
print "Script 1's name: {}".format(__name__)

तथा

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

स्क्रिप्ट 1 निष्पादित करने से आउटपुट है

Script 1's name: __main__

और स्क्रिप्ट 2 निष्पादित करने से आउटपुट है:

Script1's name is script1
Script 2's name: __main__

जैसा कि आप देख सकते हैं, __name__ हमें बताता है कि कौन सा कोड 'मुख्य' मॉड्यूल है। यह बहुत अच्छा है, क्योंकि आप केवल कोड लिख सकते हैं और सी / सी ++ जैसे संरचनात्मक मुद्दों के बारे में चिंता करने की ज़रूरत नहीं है, जहां, यदि कोई फ़ाइल 'मुख्य' फ़ंक्शन लागू नहीं करती है तो इसे निष्पादन योग्य के रूप में संकलित नहीं किया जा सकता है और यदि ऐसा होता है, इसे तब पुस्तकालय के रूप में उपयोग नहीं किया जा सकता है।

मान लें कि आप एक पायथन लिपि लिखते हैं जो कुछ बढ़िया काम करता है और आप अन्य उद्देश्यों के लिए उपयोगी कार्यों के बोतलबंद को लागू करते हैं। अगर मैं उनका उपयोग करना चाहता हूं तो मैं सिर्फ अपनी स्क्रिप्ट आयात कर सकता हूं और अपने प्रोग्राम को निष्पादित किए बिना उनका उपयोग कर सकता हूं (यह देखते हुए कि आपका कोड केवल if __name__ == "__main__": संदर्भ में निष्पादित करता है if __name__ == "__main__": संदर्भ)। जबकि सी / सी ++ में आपको उन टुकड़ों को एक अलग मॉड्यूल में विभाजित करना होगा जिसमें फ़ाइल शामिल हो। नीचे की स्थिति चित्रित करें;

तीर आयात लिंक हैं। पिछले मॉड्यूल कोड को शामिल करने की कोशिश करने वाले प्रत्येक मॉड्यूल के लिए छह फाइलें हैं (नौ, कार्यान्वयन फाइलों की गिनती) और पांच लिंक। इससे सी कोड में अन्य कोड शामिल करना मुश्किल हो जाता है जब तक कि इसे विशेष रूप से लाइब्रेरी के रूप में संकलित नहीं किया जाता है। अब इसे पायथन के लिए चित्रित करें:

आप एक मॉड्यूल लिखते हैं, और यदि कोई आपके कोड का उपयोग करना चाहता है तो वे इसे आयात करते हैं और __name__ चर लाइब्रेरी भाग से प्रोग्राम के निष्पादन योग्य हिस्से को अलग करने में मदद कर सकते हैं।




विचार करें:

if __name__ == "__main__":
    main()

यह जांचता है कि पाइथन लिपि की __name__ विशेषता "__main__" । दूसरे शब्दों में, यदि प्रोग्राम स्वयं निष्पादित किया गया है, तो विशेषता __main__ होगी, इसलिए प्रोग्राम निष्पादित किया जाएगा (इस मामले में main() फ़ंक्शन)।

हालांकि, यदि आपकी पाइथन स्क्रिप्ट का उपयोग मॉड्यूल द्वारा किया जाता है, if कथन के बाहर कोई भी कोड निष्पादित किया जाएगा, तो if \__name__ == "\__main__" का उपयोग यह जांचने के लिए किया जाता है कि प्रोग्राम को मॉड्यूल के रूप में उपयोग किया जाता है या नहीं, और इसलिए यह तय करता है कि कोड को चलाने के लिए।




सिस्टम (पायथन दुभाषिया) स्रोत फ़ाइलों (मॉड्यूल) के लिए प्रदान करता है कि कई चर हैं। जब भी आप चाहें अपने मूल्य प्राप्त कर सकते हैं, तो, हम __name__ चर / विशेषता पर ध्यान केंद्रित करते हैं:

जब पायथन एक स्रोत कोड फ़ाइल लोड करता है, तो इसमें पाए गए सभी कोड निष्पादित होते हैं। (ध्यान दें कि यह फ़ाइल में परिभाषित सभी विधियों और कार्यों को कॉल नहीं करता है, लेकिन यह उन्हें परिभाषित करता है।)

दुभाषिया स्रोत कोड फ़ाइल निष्पादित करने से पहले, यह उस फ़ाइल के लिए कुछ विशेष चर परिभाषित करता है; __name__ उन विशेष चरों में से एक है जो पायथन स्वचालित रूप से प्रत्येक स्रोत कोड फ़ाइल के लिए परिभाषित करता है।

यदि पाइथन इस स्रोत कोड फ़ाइल को मुख्य प्रोग्राम (यानी आपके द्वारा चलाए जाने वाली फ़ाइल) के रूप में लोड कर रहा है, तो यह इस फ़ाइल के लिए "__main__" मान रखने के लिए विशेष __name__ चर सेट करता है।

यदि यह किसी अन्य मॉड्यूल से आयात किया जा रहा है, तो __name__ उस मॉड्यूल के नाम पर सेट हो जाएगा।

तो, आपके उदाहरण में भाग में:

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

मतलब है कि कोड ब्लॉक:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

जब आप मॉड्यूल को सीधे चलाते हैं तो केवल तभी निष्पादित किया जाएगा; कोड ब्लॉक निष्पादित नहीं होगा यदि कोई अन्य मॉड्यूल इसे कॉल / आयात कर रहा है क्योंकि __name__ का मान उस विशेष उदाहरण में " मुख्य " के बराबर नहीं होगा।

उम्मीद है कि यह मदद करता है।




यह एक विशेष बात है जब एक पायथन फ़ाइल को कमांड लाइन से बुलाया जाता है। इसका उपयोग आम तौर पर "मुख्य ()" फ़ंक्शन को कॉल करने के लिए किया जाता है या उदाहरण के लिए कमांडलाइन तर्कों जैसे अन्य उपयुक्त स्टार्टअप कोड निष्पादित करता है।

यह कई तरीकों से लिखा जा सकता है। एक और है:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

मैं यह नहीं कह रहा हूं कि आपको इसे उत्पादन कोड में उपयोग करना चाहिए, लेकिन यह स्पष्ट करता है कि if __name__ == '__main__' बारे में "जादुई" कुछ भी नहीं है। यह Python फ़ाइलों में एक मुख्य समारोह का आह्वान करने के लिए एक अच्छा सम्मेलन है।




कारण

if __name__ == "__main__":
    main()

मुख्य रूप से आयात लॉक समस्याओं से बचने के लिए है जो सीधे कोड आयात करने से उत्पन्न होता है। यदि आपकी फ़ाइल सीधे लागू की गई थी (यह __name__ == "__main__" केस है) तो आप main() को चलाने के लिए चाहते हैं, लेकिन यदि आपका कोड आयात किया गया था तो आयातक को लॉक समस्याओं से बचने के लिए सही मुख्य मॉड्यूल से अपना कोड दर्ज करना होगा।

एक दुष्प्रभाव यह है कि आप स्वचालित रूप से एक ऐसी पद्धति पर हस्ताक्षर करते हैं जो एकाधिक प्रविष्टि बिंदुओं का समर्थन करता है। आप प्रवेश बिंदु के रूप में main() का उपयोग करके अपना प्रोग्राम चला सकते हैं, लेकिन आपको यह नहीं करना है । जबकि setup.py main() अपेक्षा करता है, अन्य उपकरण वैकल्पिक प्रविष्टि बिंदुओं का उपयोग करते हैं। उदाहरण के लिए, अपनी फ़ाइल को gunicorn प्रक्रिया के रूप में चलाने के लिए, आप main() बजाय एक app() फ़ंक्शन को परिभाषित करते हैं। जैसे ही setup.py साथ, gunicorn आपके कोड को आयात करता है ताकि आप यह नहीं चाहते कि यह आयात किए जाने पर कुछ भी करे (आयात लॉक समस्या के कारण)।




विचार करें:

print __name__

उपरोक्त के लिए आउटपुट __main__

if __name == "__main__":
  print "direct method"

उपर्युक्त कथन सत्य है और "प्रत्यक्ष विधि" प्रिंट करता है।मान लीजिए कि क्या उन्होंने इस वर्ग को अन्य कक्षा में आयात किया है, तो यह "प्रत्यक्ष विधि" प्रिंट नहीं करता है क्योंकि आयात करते समय, यह सेट हो जाएगा __name__ equal to "firstmodel name"




यदि यह .py फ़ाइल अन्य .py फ़ाइलों द्वारा आयात की जाती है, तो "अगर कथन" के तहत कोड निष्पादित नहीं किया जाएगा।

यदि यह .py python this_py.pyशैल के नीचे चलाया जाता है , या विंडोज़ में डबल क्लिक किया जाता है। "अगर कथन" के तहत कोड निष्पादित किया जाएगा।

यह आमतौर पर परीक्षण के लिए लिखा जाता है।




सभी उत्तरों ने कार्यक्षमता को काफी समझाया है। लेकिन मैं इसके उपयोग का एक उदाहरण प्रदान करूंगा जो अवधारणा को आगे बढ़ाने में मदद कर सकता है।

मान लें कि आपके पास दो पायथन फ़ाइलें हैं, a.py और b.py। अब, a.py आयात करता है b.py। हम a.py फ़ाइल चलाते हैं, जहां "आयात b.py" कोड पहले निष्पादित किया जाता है। शेष NAME कोड चलाने से पहले, फ़ाइल b.py में कोड पूरी तरह से चलाना चाहिए।

B.py कोड में कुछ कोड है जो उस फ़ाइल के लिए विशिष्ट है b.py और हम किसी अन्य फ़ाइल (b.py फ़ाइल के अलावा) नहीं चाहते हैं, जिसने इसे चलाने के लिए b.py फ़ाइल आयात की है।

तो कोड की इस पंक्ति की जांच यही है। यदि यह मुख्य फ़ाइल (यानी, b.py) कोड चला रही है, जो इस मामले में नहीं है (a.py मुख्य फ़ाइल चल रही है), तो केवल कोड निष्पादित हो जाता है।




अगर नाम == ' मुख्य ':

हम देखते हैं कि __name__ == '__main__':अक्सर कितनी बार।

यह जांचता है कि क्या एक मॉड्यूल आयात किया जा रहा है या नहीं।

दूसरे शब्दों में, ifब्लॉक के भीतर कोड केवल तभी निष्पादित किया जाएगा जब कोड सीधे चलता है। यहां directlyमतलब है not imported

आइए देखते हैं कि यह एक साधारण कोड का उपयोग करके क्या करता है जो मॉड्यूल के नाम को प्रिंट करता है:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

यदि हम सीधे कोड चलाते हैं python test.py, तो मॉड्यूल का नाम है __main__:

call test()
test module name=__main__



Related