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


6055

निम्नलिखित कोड को देखते हुए, क्या करता 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__":ब्लॉक की स्थिति को अजगर 3 के रूप में दूर किया गया है / बाधित किया गया है? मैंने पाया है कि कुछ जानकारी बताते हुए।
carloswm85

1
@ carloswm85 यह सच नहीं है।
जियोगोस मायिरिंथ

जवाबों:


6634

जब भी पायथन इंटरप्रेटर एक स्रोत फ़ाइल पढ़ता है, तो यह दो काम करता है:

  • यह कुछ विशेष चर सेट करता है __name__, और फिर

  • यह फ़ाइल में पाए गए सभी कोड को निष्पादित करता है।

आइए देखें कि यह कैसे काम करता है और यह आपके प्रश्न से संबंधित है कि __name__चेक हम हमेशा पायथन स्क्रिप्ट में देखते हैं।

कोड नमूना

आइए आयात और स्क्रिप्ट कैसे काम करते हैं, यह पता लगाने के लिए थोड़ा अलग कोड नमूने का उपयोग करें। मान लीजिए निम्नलिखित एक फ़ाइल में है foo.py

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

विशेष चर

जब पायथन इंटरपीटर एक स्रोत फ़ाइल पढ़ता है, तो यह पहले कुछ विशेष चर को परिभाषित करता है। इस मामले में, हम __name__चर के बारे में परवाह करते हैं।

जब आपका मॉड्यूल मुख्य कार्यक्रम है

यदि आप अपने मॉड्यूल (स्रोत फ़ाइल) को मुख्य कार्यक्रम के रूप में चला रहे हैं, जैसे

python foo.py

दुभाषिया हार्ड-कोडित स्ट्रिंग "__main__"को __name__चर पर असाइन करेगा , अर्थात

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

जब आपका मॉड्यूल दूसरे द्वारा आयात किया जाता है

दूसरी ओर, मान लीजिए कि कुछ अन्य मॉड्यूल मुख्य कार्यक्रम है और यह आपके मॉड्यूल को आयात करता है। इसका मतलब है कि मुख्य कार्यक्रम में इस तरह का एक बयान है, या किसी अन्य मॉड्यूल में मुख्य कार्यक्रम आयात है:

# Suppose this is in some other main program.
import foo

दुभाषिया आपकी foo.pyफ़ाइल के लिए खोज करेगा (कुछ अन्य वेरिएंट की खोज के साथ), और उस मॉड्यूल को निष्पादित करने से पहले, यह "foo"आयात विवरण से __name__चर तक नाम को निर्दिष्ट करेगा , अर्थात

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

मॉड्यूल के कोड को निष्पादित करना

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

हमेशा

  1. यह स्ट्रिंग "before import"(बिना उद्धरण) के प्रिंट करता है ।

  2. यह mathमॉड्यूल को लोड करता है और इसे एक चर कहलाता है math। यह import mathनिम्नलिखित के साथ प्रतिस्थापित करने के बराबर है (ध्यान दें कि __import__पायथन में एक निम्न-स्तरीय फ़ंक्शन है जो एक स्ट्रिंग लेता है और वास्तविक आयात को ट्रिगर करता है):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. यह स्ट्रिंग को प्रिंट करता है "before functionA"

  2. यह defब्लॉक को निष्पादित करता है , एक फंक्शन ऑब्जेक्ट बनाता है, फिर उस फंक्शन ऑब्जेक्ट को एक वैरिएबल को असाइन करता है functionA

  3. यह स्ट्रिंग को प्रिंट करता है "before functionB"

  4. यह दूसरे defब्लॉक ऑब्जेक्ट को निष्पादित करता है , जो एक अन्य फ़ंक्शन ऑब्जेक्ट बनाता है, फिर इसे एक वैरिएबल को असाइन करता है जिसे कहा जाता है functionB

  5. यह स्ट्रिंग को प्रिंट करता है "before __name__ guard"

केवल जब आपका मॉड्यूल मुख्य कार्यक्रम है

  1. यदि आपका मॉड्यूल मुख्य कार्यक्रम है, तो यह देखेगा कि __name__वास्तव में "__main__"इसे सेट किया गया था और यह दो कार्यों को कॉल करता है, स्ट्रिंग्स को प्रिंट करना "Function A"और "Function B 10.0"

केवल जब आपका मॉड्यूल दूसरे द्वारा आयात किया जाता है

  1. ( बजाय ) यदि आपका मॉड्यूल मुख्य कार्यक्रम नहीं है, लेकिन किसी अन्य द्वारा आयात किया गया था, तो __name__वह होगा "foo", नहीं "__main__", और यह ifकथन के शरीर को छोड़ देगा ।

हमेशा

  1. यह "after __name__ guard"दोनों स्थितियों में स्ट्रिंग को प्रिंट करेगा ।

सारांश

सारांश में, यहाँ दो मामलों में क्या छपा होगा:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

क्यों यह इस तरह से काम करता है?

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

  • आपका मॉड्यूल एक पुस्तकालय है, लेकिन आप एक स्क्रिप्ट मोड चाहते हैं जहां यह कुछ इकाई परीक्षण या डेमो चलाता है।

  • आपके मॉड्यूल का उपयोग केवल एक मुख्य कार्यक्रम के रूप में किया जाता है, लेकिन इसमें कुछ इकाई परीक्षण होते हैं, और परीक्षण की रूपरेखा .pyआपकी स्क्रिप्ट जैसी फ़ाइलों को आयात करके और अन्य परीक्षण कार्यों को चलाकर काम करती है। आप इसे स्क्रिप्ट चलाने की कोशिश नहीं करना चाहते हैं क्योंकि यह मॉड्यूल आयात कर रहा है।

  • आपका मॉड्यूल ज्यादातर एक मुख्य कार्यक्रम के रूप में उपयोग किया जाता है, लेकिन यह उन्नत उपयोगकर्ताओं के लिए प्रोग्रामर-अनुकूल एपीआई भी प्रदान करता है।

उन उदाहरणों से परे, यह सुरुचिपूर्ण है कि पायथन में एक स्क्रिप्ट चलाना केवल कुछ जादुई चर स्थापित करना और स्क्रिप्ट आयात करना है। "रनिंग" स्क्रिप्ट स्क्रिप्ट के मॉड्यूल को आयात करने का एक साइड इफेक्ट है।

सोच के लिए भोजन

  • प्रश्न: क्या मेरे पास कई __name__चेकिंग ब्लॉक हो सकते हैं? उत्तर: ऐसा करना अजीब है, लेकिन भाषा आपको रोक नहीं पाएगी।

  • मान लीजिए निम्नलिखित में है foo2.py। यदि आप python foo2.pyकमांड-लाइन पर कहते हैं तो क्या होता है ? क्यों?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • अब, यदि आप __name__चेक को निकालते हैं तो क्या होगा foo3.py:
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • स्क्रिप्ट के रूप में उपयोग किए जाने पर यह क्या करेगा? जब एक मॉड्यूल के रूप में आयात किया जाता है?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

14
जिज्ञासा से बाहर: अगर मैं subprocess.run('foo_bar.py')अजगर लिपि में चलाऊं तो क्या होगा ? मुझे लगता है कि जब मैं cmd में मैन्युअल रूप से tipe करता हूं, उसी तरह foo_barशुरू किया जाएगा । क्या यह मामला है? खाते में @MrFooz का उत्तर देते हुए ऐसा करने में कोई समस्या नहीं होनी चाहिए और एक बार में मुझे जितने "मुख्य" मॉड्यूल पसंद हैं। यहां तक ​​कि मूल्य को बदलने या स्वतंत्र रूप से कई होने से एक-दूसरे के साथ बातचीत (या एक-दूसरे को पैदा करने वाले उदाहरण ) पैदा होते हैं , जिन्हें पाइथन के लिए हमेशा की तरह व्यापार होना चाहिए। क्या मुझे कुछ याद है? __name__ = '__main__'foo_bar.py__name__subprocess
16

12
@hajef आप सही हैं कि चीजें किस तरह से काम करेंगी subprocess.run। उन्होंने कहा, लिपियों के बीच कोड साझा करने का एक आम तौर पर बेहतर तरीका मॉड्यूल बनाना है और स्क्रिप्ट को एक-दूसरे को स्क्रिप्ट के रूप में लागू करने के बजाय साझा मॉड्यूल को कॉल करना है। subprocess.runकॉल डिबग करना कठिन है क्योंकि अधिकांश डिबगर प्रक्रिया सीमाओं में नहीं कूदते हैं, यह अतिरिक्त प्रक्रियाओं को बनाने और नष्ट करने के लिए गैर-तुच्छ प्रणाली ओवरहेड जोड़ सकता है, आदि
श्री Fooz

4
मुझे विचार अनुभाग के लिए भोजन में foo2.py उदाहरण में संदेह है। foo2.py आयात फ़ंक्शन से क्या करता है? मेरे विचार में, यह फंक्शन 2 से foo2.py आयात करता है
user471651

1
@MrFooz मैं इस एक्सडी की तरह कुछ भी करने का इरादा कभी नहीं करता था यह मेरे दिमाग में आया और मुझे एहसास हुआ कि संभवतः पीपीएल की मदद करने के लिए यह काफी अजीब था। इस तरह के सामान के इर्द-गिर्द अपने मन को लपेट लेना। @ user471651 क्यों from foo2 import functionBfunctionB से foo2 आयात करना चाहिए ? यह एक अर्थ संबंधी गर्भनिरोधक है। from module import methodमोडुल से विधि आयात करता है।
15

2
मॉड्यूल में से एक जो आपके कोड को आयात कर सकता है multiprocessing, विशेष रूप से विंडोज पर इस परीक्षण को आवश्यक बनाता है।
यान वर्नियर

1800

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

python myscript.py

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

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

if __name__ == "__main__":
    ...

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

# 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

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


बहुत बढ़िया जवाब, यह मेरी राय में सबसे स्पष्ट जवाब था। +1!
TheTechRobo36414519

+1 इसके बारे में सोचने के तरीके के लिए: पहली इंडेंटेड लाइन को केवल पहली बार चलाया जाता है, जब तक कि आप उस पहली लाइन पर फ़ंक्शंस नहीं चलाते हैं
एली थेमन

719

के लिए सबसे सरल स्पष्टीकरण __name__चर (imho) के निम्नलिखित है:

निम्न फ़ाइलें बनाएँ।

# a.py
import b

तथा

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

उन्हें चलाने से आपको यह आउटपुट मिलेगा:

$ python a.py
Hello World from b!

जैसा कि आप देख सकते हैं, जब एक मॉड्यूल आयात किया जाता है, तो पायथन globals()['__name__']इस मॉड्यूल में मॉड्यूल के नाम पर सेट होता है। इसके अलावा, मॉड्यूल में सभी कोड आयात करने पर चलाया जा रहा है। जैसा कि ifकथन Falseइस भाग का मूल्यांकन करता है, निष्पादित नहीं किया जाता है।

$ python b.py
Hello World from __main__!
Hello World again from __main__!

जैसा कि आप देख सकते हैं, जब किसी फ़ाइल को निष्पादित किया जाता है, तो पायथन globals()['__name__']इस फ़ाइल में सेट हो जाता है "__main__"। इस बार, ifकथन का मूल्यांकन किया Trueजा रहा है और चलाया जा रहा है।


513

क्या करता 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()

125

if __name__ == "__main__"वह भाग जो स्क्रिप्ट के चलने पर (कमांड से) कमांड लाइन का उपयोग करता है python myscript.py


2
क्यों एक फ़ाइल है helloworld.pyबस के साथ print("hello world")उस में आदेश के साथ चला सकते हैं python helloworld.pyहै, भले ही कोई if __name__ == "__main__"?
hi15

83

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

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

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

python mycode.py

अन्यथा अनाम वैश्विक नामस्थान '__main__'को इसका मान सौंपा गया है __name__

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

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

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

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

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

72

कोड के यांत्रिकी पर बहुत सारे अलग-अलग तरीके हैं यहां "हाउ", लेकिन मेरे लिए इसका कोई मतलब नहीं था जब तक कि मैंने "क्यों" को नहीं समझा। नए प्रोग्रामर के लिए यह विशेष रूप से सहायक होना चाहिए।

फ़ाइल "ab.py" लें:

def a():
    print('A function in ab file');
a()

और एक दूसरी फ़ाइल "xy.py":

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

यह कोड वास्तव में क्या कर रहा है?

जब आप निष्पादित करते हैं xy.py, तो आप import ab। आयात विवरण आयात पर मॉड्यूल को तुरंत चलाता है, इसलिए abशेष के संचालन से पहले संचालन निष्पादित किया जाता है xy। एक बार समाप्त होने के बाद ab, यह जारी हैxy

दुभाषिया ट्रैक रखता है कि कौन सी स्क्रिप्ट के साथ चल रहे हैं __name__। जब आप एक स्क्रिप्ट चलाते हैं - कोई बात नहीं आपने इसे क्या नाम दिया है - दुभाषिया इसे कॉल करता है "__main__", इसे मास्टर या 'होम' स्क्रिप्ट बनाता है जो बाहरी स्क्रिप्ट चलाने के बाद वापस आ जाता है।

कोई अन्य स्क्रिप्ट जिसे इस "__main__"स्क्रिप्ट से बुलाया जाता है, उसका फ़ाइल नाम इसके __name__(जैसे, __name__ == "ab.py") के रूप में असाइन किया गया है । इसलिए, लाइनif __name__ == "__main__": यह निर्धारित करने के लिए दुभाषिया का परीक्षण है कि क्या वह 'होम' स्क्रिप्ट की व्याख्या कर रही है / जो कि शुरू में निष्पादित हुई थी, या यदि वह अस्थायी रूप से दूसरी (बाहरी) स्क्रिप्ट में झांक रही है। यह प्रोग्रामर को लचीलापन देता है कि स्क्रिप्ट को अलग तरह से व्यवहार करना है अगर इसे सीधे निष्पादित किया जाता है बनाम बाहरी रूप से कहा जाता है।

आइए उपरोक्त कोड के माध्यम से यह समझने के लिए कि क्या हो रहा है, पहले बिना पढ़े लाइनों और स्क्रिप्ट में दिखाई देने वाले क्रम पर ध्यान केंद्रित करें। उस फ़ंक्शन को याद रखें - या def- ब्लॉक तब तक खुद से कुछ भी नहीं करते हैं जब तक कि उन्हें कॉल न किया जाए। अगर दुखी होकर खुद से कहा जाए तो दुभाषिया क्या कह सकता है:

  • 'घर' फ़ाइल के रूप में xy.py खोलें; इसे चर "__main__"में बुलाओ __name__
  • आयात करें और फ़ाइल को खोलें __name__ == "ab.py"
  • ओह, एक समारोह। मैं याद रखूँगा कि।
  • ठीक है, कार्य a(); मैंने बस यही सीखा है। ' ए फंक्शन इन एब फाइल ' प्रिंटिंग ।
  • फाइल समाप्त; वापस करने के लिए "__main__"!
  • ओह, एक समारोह। मैं याद रखूँगा कि।
  • और एक।
  • कार्य x(); ठीक है, मुद्रण ' परिधीय कार्य: अन्य परियोजनाओं में उपयोगी हो सकता है '।
  • यह क्या है? एक ifबयान। खैर, शर्त पूरी हो गई है (चर __name__को सेट कर दिया गया है "__main__"), इसलिए मैं main()फ़ंक्शन में प्रवेश करूंगा और ' मुख्य फ़ंक्शन: यह वह जगह है जहां कार्रवाई ' है।

नीचे की दो पंक्तियों का अर्थ है: "यदि यह "__main__"या 'होम' स्क्रिप्ट है, तो फंक्शन को निष्पादित करें main()"। इसीलिए आपको एक def main():ब्लॉक अप टॉप दिखाई देगा , जिसमें स्क्रिप्ट की कार्यक्षमता का मुख्य प्रवाह होता है।

इसे क्यों लागू करें?

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

फिर से, अपवाद होंगे, लेकिन सामान्य अभ्यास यह है कि main()आमतौर पर बाहरी रूप से नहीं बुलाया जाता है। तो आप एक और बात सोच रहे होंगे: अगर हम फोन नहीं कर रहे हैं main(), तो हम स्क्रिप्ट को क्यों बुला रहे हैं? ऐसा इसलिए है क्योंकि बहुत से लोग स्टैंडअलोन फ़ंक्शन के साथ अपनी स्क्रिप्ट को बनाते हैं जो फ़ाइल में बाकी कोड से स्वतंत्र होने के लिए बनाए जाते हैं। वे बाद में स्क्रिप्ट के शरीर में कहीं और बुलाए गए। जो मुझे इस पर लाता है:

लेकिन कोड इसके बिना काम करता है

हाँ य़ह सही हैं। इन अलग-अलग कार्यों को एक इन-लाइन स्क्रिप्ट से बुलाया जा सकता है जो किसी main()फ़ंक्शन के अंदर निहित नहीं है। यदि आप इन-लाइन स्क्रिप्ट बनाने के लिए आदी हैं (जैसा कि मैं प्रोग्रामिंग के अपने शुरुआती सीखने के चरणों में) हूं, तो इन-लाइन स्क्रिप्ट का निर्माण करें जो आपको आवश्यक हैं, और यदि आपको कभी भी उस ऑपरेशन की आवश्यकता होती है तो आप इसे फिर से जानने की कोशिश करेंगे। ठीक है, आप अपने कोड में इस तरह की आंतरिक संरचना के लिए उपयोग नहीं किए जाते हैं, क्योंकि यह निर्माण करने के लिए अधिक जटिल है और यह पढ़ने के लिए सहज नहीं है।

लेकिन यह एक स्क्रिप्ट है जो संभवतः अपने कार्यों को बाहरी रूप से नहीं कह सकती है, क्योंकि अगर यह ऐसा होता है तो तुरंत चर की गणना और असाइन करना शुरू कर देगा। और संभावना है कि यदि आप किसी फ़ंक्शन को फिर से उपयोग करने का प्रयास कर रहे हैं, तो आपकी नई स्क्रिप्ट पुराने से काफी निकट से संबंधित है कि परस्पर विरोधी चर होंगे।

स्वतंत्र कार्यों को विभाजित करने में, आप अपने पिछले काम को किसी अन्य स्क्रिप्ट में कॉल करके फिर से उपयोग करने की क्षमता प्राप्त करते हैं। उदाहरण के लिए, "example.py" "xy.py" से कॉल और आयात कर सकता है x(), जिससे "xy.py" से 'x' फ़ंक्शन का उपयोग किया जा सकता है। (हो सकता है कि यह किसी दिए गए टेक्स्ट स्ट्रिंग के तीसरे शब्द को कैपिटलाइज़ कर रहा हो; संख्याओं की सूची से एक NumPy सरणी बनाना और उन्हें स्क्वेर करना; या एक 3D सतह को अलग करना। संभावनाएं असीम हैं।)

(एक तरफ के रूप में, इस प्रश्न में @kindall का एक उत्तर शामिल है जिसने आखिरकार मुझे समझने में मदद की - क्यों, कैसे नहीं। दुर्भाग्य से इसे इस एक के डुप्लिकेट के रूप में चिह्नित किया गया है , जो मुझे लगता है कि एक गलती है।)


52

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

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

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


43

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

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

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

तथा

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

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

Script 1's name: __main__

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

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

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

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

C में जटिल आयात

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

पायथन में सुरुचिपूर्ण आयात

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


2
C / C ++ चित्रण गलत है: एक ही यूनिट नाम ( फ़ाइल 1 ) का 3 गुना ।
वुल्फ

40

आइए उत्तर को और अधिक सार तरीके से देखें:

मान लीजिए हमारे पास यह कोड है x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

जब हम दौड़ रहे होते हैं तो ब्लॉक ए और बी चलाए जाते हैं x.py

लेकिन ब्लॉक ए (और बी नहीं) चलाया जाता है जब हम एक और मॉड्यूल चला रहे हैं, y.pyउदाहरण के लिए, जिसमें x.pyआयात किया जाता है और कोड वहां से चलाया जाता है (जैसे कि जब कोई फ़ंक्शन x.pyसे कॉल किया जाता है y.py)।


1
मैं पोस्ट को संपादित करने में सक्षम नहीं था (यदि आवश्यक हो तो न्यूनतम 6 वर्ण)। लाइन 14 में 'x.py' की बजाय 'xy' है।
हमेशा

35

जब आप पाइथन को अंतःक्रियात्मक रूप से चलाते हैं तो स्थानीय __name__चर का मान दिया जाता है __main__। इसी तरह, जब आप कमांड लाइन से एक पायथन मॉड्यूल को निष्पादित करते हैं, तो इसे किसी अन्य मॉड्यूल में आयात करने के बजाय, इसके __name__विशेषता को मॉड्यूल __main__के वास्तविक नाम के बजाय एक मान दिया जाता है। इस तरह, मॉड्यूल स्वयं के __name__लिए अपने स्वयं के मूल्य को देख सकते हैं कि वे कैसे उपयोग किए जा रहे हैं, चाहे वह किसी अन्य प्रोग्राम के लिए समर्थन के रूप में या कमांड लाइन से निष्पादित मुख्य एप्लिकेशन के रूप में। इस प्रकार, पायथन मॉड्यूल में निम्नलिखित मुहावरे काफी सामान्य हैं:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

34

विचार करें:

if __name__ == "__main__":
    main()

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

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


ऐसा लगता है कि चमकदार उत्तर +1
एसएनआर

27

इसके बारे में कुछ भी समझाने से पहले if __name__ == '__main__'यह समझना जरूरी __name__है कि यह क्या है और क्या करता है।

क्या है __name__?

__name__एक DunderAlias ​​है - एक वैश्विक चर (मॉड्यूल से सुलभ) के रूप में सोचा जा सकता है और इसी तरह से काम करता है global

यह एक स्ट्रिंग (वैश्विक जैसा कि ऊपर उल्लेख) के रूप में ने संकेत दिया है type(__name__)(उपज <class 'str'>), और दोनों के लिए एक इनबिल्ट मानक है अजगर 3 और अजगर 2 संस्करणों।

कहाँ पे:

यह न केवल लिपियों में उपयोग किया जा सकता है, बल्कि दुभाषिया और मॉड्यूल / पैकेज दोनों में भी पाया जा सकता है।

दुभाषिया:

>>> print(__name__)
__main__
>>>

स्क्रिप्ट:

test_file.py :

print(__name__)

जिसके परिणामस्वरूप __main__

मॉड्यूल या पैकेज:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

जिसके परिणामस्वरूप somefile

ध्यान दें कि जब पैकेज या मॉड्यूल में उपयोग किया जाता है, __name__तो फ़ाइल का नाम लेता है। वास्तविक मॉड्यूल या पैकेज पथ का मार्ग नहीं दिया गया है, लेकिन इसकी अपनी DunderAlias ​​है __file__, जो इसके लिए अनुमति देता है।

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

अभ्यास:

वैरिएबल होने का मतलब है कि यह मूल्य अधिलेखित किया जा सकता है ("कर सकते हैं" का अर्थ "नहीं होना चाहिए"), अधिलेखित मूल्य के __name__परिणामस्वरूप पठनीयता की कमी होगी। तो किसी भी कारण से ऐसा न करें। यदि आपको एक चर की आवश्यकता है तो एक नया चर परिभाषित करें।

यह हमेशा माना जाता है कि के मूल्य में __name__होने के लिए __main__या फ़ाइल का नाम। एक बार फिर इस डिफ़ॉल्ट मान को बदलने से अधिक भ्रम पैदा होगा कि यह अच्छा करेगा, जिससे समस्या और भी कम हो जाएगी।

उदाहरण:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

if __name__ == '__main__'लिपियों में शामिल करने के लिए इसे सामान्य रूप से अच्छा अभ्यास माना जाता है ।

अब जवाब देने के लिए if __name__ == '__main__':

अब हम जानते हैं कि __name__चीजों का व्यवहार स्पष्ट हो गया है:

एक ifफ्लो कंट्रोल स्टेटमेंट होता है जिसमें कोड का ब्लॉक होता है जो दिए गए मान के सही होने पर निष्पादित होता है। हमने देखा है कि __name__या तो ले जा सकते हैं __main__या फ़ाइल नाम से आयात किया गया है।

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

यदि वास्तव __name__में मूल्य लेता है __main__तो कोड के उस ब्लॉक में जो भी है वह निष्पादित करेगा।

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

मॉड्यूल:

__name__ मॉड्यूल के नाम को परिभाषित करने के लिए मॉड्यूल में भी इस्तेमाल किया जा सकता है

प्रकार:

अन्य, कम सामान्य लेकिन उपयोगी चीजों के साथ करना संभव है __name__, कुछ मैं यहां दिखाऊंगा:

यदि फ़ाइल एक मॉड्यूल या पैकेज है, तो केवल निष्पादन:

if __name__ != '__main__':
    # Do some useful things 

यदि फ़ाइल मुख्य एक है और दूसरी स्थिति में यदि वह नहीं है तो उसे चलाना:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

आप पुस्तकालयों के विस्तृत उपयोग के बिना पैकेजों और मॉड्यूलों पर रननीय मदद कार्यों / उपयोगिताओं को प्रदान करने के लिए भी इसका उपयोग कर सकते हैं।

यह मुख्य स्क्रिप्ट के रूप में कमांड लाइन से मॉड्यूल को चलाने की अनुमति देता है, जो बहुत उपयोगी भी हो सकता है।


25

मुझे लगता है कि उत्तर को गहराई से और सरल शब्दों में तोड़ना सबसे अच्छा है:

__name__: पायथन में प्रत्येक मॉड्यूल में एक विशेष विशेषता होती है जिसे कहा जाता है __name__। यह एक अंतर्निहित वैरिएबल है जो मॉड्यूल का नाम लौटाता है।

__main__: अन्य प्रोग्रामिंग भाषाओं की तरह, पायथन में भी एक निष्पादन प्रविष्टि बिंदु है, अर्थात, मुख्य। '__main__' उस स्कोप का नाम है जिसमें शीर्ष-स्तरीय कोड निष्पादित होता है । मूल रूप से आपके पास पायथन मॉड्यूल का उपयोग करने के दो तरीके हैं: इसे सीधे स्क्रिप्ट के रूप में चलाएं, या इसे आयात करें। जब एक मॉड्यूल को स्क्रिप्ट के रूप में चलाया जाता है, तो इसका __name__सेट किया जाता है __main__

इस प्रकार, मॉड्यूल के मुख्य कार्यक्रम के रूप में चलने पर __name__विशेषता का मान सेट किया __main__जाता है। अन्यथा __name__ मॉड्यूल का नाम सम्‍मिलित करने के लिए मान सेट किया गया है।


23

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

इसे कई तरह से लिखा जा सकता था। एक और है:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

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


7
मैं इस बुरे रूप पर विचार करूंगा क्योंकि आप 1) साइड इफेक्ट्स पर भरोसा कर रहे हैं और 2) गाली दे रहे हैं andandयह जाँचने के लिए उपयोग किया जाता है कि क्या दो बूलियन कथन दोनों सत्य हैं। चूंकि आप के परिणाम में कोई दिलचस्पी नहीं रखते हैं and, एक ifबयान अधिक स्पष्ट रूप से आपके इरादों को सूचित करता है।
jpmc26

8
बूलियन ऑपरेटरों के शॉर्ट-सर्किट व्यवहार का फ्लो कंट्रोल मैकेनिज्म के रूप में शोषण करना है या नहीं, इस सवाल को छोड़ दें, तो बड़ी समस्या यह है कि यह सवाल का बिल्कुल भी जवाब नहीं देता है
मार्क ऐमी

@ मकर्मी हा, शीश, अब करता है। F
प्रो। फॉकन अनुबंध ने

19

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

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

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

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

यदि इसे किसी अन्य मॉड्यूल से आयात किया जा रहा है, तो __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__ का मान उस विशेष उदाहरण में " मुख्य " के बराबर नहीं होगा ।

आशा है कि यह मदद करता है।


17

if __name__ == "__main__": मूल रूप से शीर्ष-स्तरीय स्क्रिप्ट वातावरण है, और यह दुभाषिया को निर्दिष्ट करता है कि ('पहले निष्पादित होने के लिए मेरी सर्वोच्च प्राथमिकता है')।

'__main__'उस स्कोप का नाम है जिसमें शीर्ष-स्तरीय कोड निष्पादित होता है। जब मानक इनपुट, स्क्रिप्ट, या एक इंटरैक्टिव प्रॉम्प्ट से पढ़ा __name__जाता है, '__main__'तो एक मॉड्यूल सेट होता है ।

if __name__ == "__main__":
    # Execute only if run as a script
    main()

17

मैं इस पृष्ठ पर पूरे उत्तर में बहुत पढ़ रहा हूं। मैं कहूंगा, यदि आप बात जानते हैं, तो निश्चित रूप से आप उन उत्तरों को समझेंगे, अन्यथा, आप अभी भी भ्रमित हैं।

छोटा होने के लिए, आपको कई बिंदुओं को जानना होगा:

  1. import a कार्रवाई वास्तव में "ए" में चलाई जा सकती है

  2. बिंदु 1 के कारण, आप नहीं चाहते कि सब कुछ आयात करते समय "a" में चला जाए

  3. बिंदु 2 में समस्या को हल करने के लिए, अजगर आपको एक शर्त जांचने की अनुमति देता है

  4. __name__सभी .pyमॉड्यूल में एक अंतर्निहित चर है ; जब a.pyआयात किया जाता है, का मूल्य __name__की a.pyमॉड्यूल अपनी फ़ाइल नाम "पर सेट है a"; जब a.pyसीधे का उपयोग कर "चलाया जाता है python a.py" है, जो साधन a.pyप्रवेश बिंदु है, तो के मूल्य __name__के a.pyमॉड्यूल एक स्ट्रिंग पर सेट है__main__

  5. कैसे तंत्र के आधार पर अजगर __name__प्रत्येक मॉड्यूल के लिए चर सेट करता है , क्या आप जानते हैं कि बिंदु 3 कैसे प्राप्त करें? जवाब काफी आसान है, है ना? अगर एक शर्त रखो if __name__ == "__main__": ...:; आप __name__ == "a"अपनी कार्यात्मक आवश्यकता के आधार पर भी डाल सकते हैं

अजगर महत्वपूर्ण बात यह है कि बिंदु 4 पर है! बाकी सिर्फ बुनियादी तर्क है।


1
हां, बिंदु 1 समझना जरूरी है। उससे इस तंत्र की आवश्यकता स्पष्ट हो जाती है।
यूरेका

16

विचार करें:

print __name__

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

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

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


14

आप फ़ाइल को स्क्रिप्ट के साथ-साथ आयात करने योग्य मॉड्यूल के रूप में प्रयोग करने योग्य बना सकते हैं ।

fibo.py (नाम का एक मॉड्यूल fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

संदर्भ: https://docs.python.org/3.5/tutorial/modules.html


14

कारण

if __name__ == "__main__":
    main()

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

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


3
आयात ताला के बारे में जानने के लिए अच्छा है । क्या आप कृपया एक कार्यप्रणाली पर हस्ताक्षर करने के लिए समझा सकते हैं कि [...] थोड़ा और हिस्सा?
वुल्फ

1
@ भेड़िया: ज़रूर। मैंने कई प्रविष्टि बिंदु कार्यप्रणाली के बारे में कुछ वाक्य जोड़े हैं।
personal_cloud

11

यह जवाब पायथन सीखने वाले जावा प्रोग्रामर्स के लिए है। हर जावा फ़ाइल में आमतौर पर एक सार्वजनिक वर्ग होता है। आप उस वर्ग का दो तरह से उपयोग कर सकते हैं:

  1. अन्य फ़ाइलों से कक्षा को कॉल करें। आपको बस इसे कॉलिंग प्रोग्राम में इम्पोर्ट करना होगा।

  2. परीक्षण प्रयोजनों के लिए अकेले कक्षा स्टैंड चलाएं।

उत्तरार्द्ध मामले के लिए, कक्षा में एक सार्वजनिक स्थैतिक शून्य मुख्य () विधि होनी चाहिए। पायथन में यह उद्देश्य विश्व स्तर पर परिभाषित लेबल द्वारा दिया गया है '__main__'


11

अंडर कोड केवल तब निष्पादित किया if __name__ == '__main__': जाएगा जब मॉड्यूल को स्क्रिप्ट के रूप में लागू किया जाता है

एक उदाहरण के रूप में निम्नलिखित मॉड्यूल पर विचार करें my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

पहली संभावना: my_test_module.pyदूसरे मॉड्यूल में आयात

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

अब यदि आप आह्वान करते हैं main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

ध्यान दें कि केवल शीर्ष-स्तरीय print()विवरण my_test_moduleनिष्पादित किया गया है।


दूसरी संभावना: my_test_module.pyएक स्क्रिप्ट के रूप में आमंत्रित करें

अब यदि आप my_test_module.pyपायथन लिपि के रूप में चलते हैं , तो दोनों print()कथनों को समाप्त कर दिया जाएगा:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

10

अजगर में प्रत्येक मॉड्यूल में एक विशेषता होती है जिसे कहा जाता है __name____name__ विशेषता का मूल्य __main__ तब होता है जब मॉड्यूल को सीधे चलाया जाता है, जैसे python my_module.py। अन्यथा (जैसे जब आप कहते हैं import my_module) का मान __name__ मॉड्यूल का नाम है।

संक्षेप में समझाने के लिए छोटा उदाहरण।

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

हम इसे सीधे निष्पादित कर सकते हैं

python test.py  

उत्पादन

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

अब मान लें कि हम अन्य स्क्रिप्ट से स्क्रिप्ट के ऊपर कॉल करते हैं

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

जब आप इस पर अमल करते हैं

python external_calling.py

उत्पादन

42
I am inside hello_world
test

तो, ऊपर आत्म है कि जब आप अन्य स्क्रिप्ट से परीक्षण कहते हैं, अगर पाश व्याख्यात्मक है __name__में test.pyनिष्पादित नहीं होंगे।


6

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

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

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


6

यदि अजगर दुभाषिया एक विशेष मॉड्यूल चला रहा है तो __name__वैश्विक चर का मूल्य होगा"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

जब आप इस स्क्रिप्ट को प्रिंट करते हैं तो आप मुझे देख सकते हैं

यदि आप इस फ़ाइल को आयात करते हैं तो A को B फ़ाइल करें और फ़ाइल B को निष्पादित करें तो if __name__ == "__main__"फ़ाइल A झूठी हो जाती है, इसलिए यह प्रिंट करता है आप मुझे नहीं देख सकते


5

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

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

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

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


4

एक फ़ाइल बनाएँ, a Oracle :

print(__name__) # It will print out __main__

__name____main__जब भी उस फ़ाइल को सीधे चलाया जाता है, तो यह बराबर होता है कि यह मुख्य फ़ाइल है।

एक ही डायरेक्टरी में एक और फाइल बनाएं, बीडीओम :

import a  # Prints a

चलाओ। यह एक , अर्थात, आयात की गई फ़ाइल का नाम मुद्रित करेगा ।

इसलिए, एक ही फाइल के दो अलग-अलग व्यवहार दिखाने के लिए , यह आमतौर पर इस्तेमाल की जाने वाली ट्रिक है:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

4

यदि नाम == ' मुख्य ':

हम देखते हैं अगर __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__

4

बस, यह फ़ाइल को चलाने के लिए प्रवेश बिंदु है, सी प्रोग्रामिंग भाषा mainमें फ़ंक्शन की तरह ।


8
यह उत्तर यह धारणा बनाता है कि ओपी (या एक समान प्रश्न वाला कोई भी उपयोगकर्ता) सी से परिचित है और जानता है कि प्रवेश बिंदु क्या है।
arredond

1
यह उत्तर यह भी मानता है कि कोई भी कोड (साइड इफेक्ट के बिना परिभाषाओं के अलावा) if __name__ == "__main__"ब्लॉक से पहले नहीं होता है। तकनीकी रूप से निष्पादित स्क्रिप्ट का शीर्ष कार्यक्रम का प्रवेश बिंदु है।
चार्ली हार्डिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.