जब भी पायथन इंटरप्रेटर एक स्रोत फ़ाइल पढ़ता है, तो यह दो काम करता है:
आइए देखें कि यह कैसे काम करता है और यह आपके प्रश्न से संबंधित है कि __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"
मॉड्यूल के कोड को निष्पादित करना
विशेष चर सेट होने के बाद, दुभाषिया मॉड्यूल में सभी कोड को निष्पादित करता है, एक समय में एक बयान। आप कोड नमूने के साथ एक और विंडो खोलना चाहते हैं ताकि आप इस स्पष्टीकरण के साथ अनुसरण कर सकें।
हमेशा
यह स्ट्रिंग "before import"
(बिना उद्धरण) के प्रिंट करता है ।
यह 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")
यह स्ट्रिंग को प्रिंट करता है "before functionA"
।
यह def
ब्लॉक को निष्पादित करता है , एक फंक्शन ऑब्जेक्ट बनाता है, फिर उस फंक्शन ऑब्जेक्ट को एक वैरिएबल को असाइन करता है functionA
।
यह स्ट्रिंग को प्रिंट करता है "before functionB"
।
यह दूसरे def
ब्लॉक ऑब्जेक्ट को निष्पादित करता है , जो एक अन्य फ़ंक्शन ऑब्जेक्ट बनाता है, फिर इसे एक वैरिएबल को असाइन करता है जिसे कहा जाता है functionB
।
यह स्ट्रिंग को प्रिंट करता है "before __name__ guard"
।
केवल जब आपका मॉड्यूल मुख्य कार्यक्रम है
- यदि आपका मॉड्यूल मुख्य कार्यक्रम है, तो यह देखेगा कि
__name__
वास्तव में "__main__"
इसे सेट किया गया था और यह दो कार्यों को कॉल करता है, स्ट्रिंग्स को प्रिंट करना "Function A"
और "Function B 10.0"
।
केवल जब आपका मॉड्यूल दूसरे द्वारा आयात किया जाता है
- ( बजाय ) यदि आपका मॉड्यूल मुख्य कार्यक्रम नहीं है, लेकिन किसी अन्य द्वारा आयात किया गया था, तो
__name__
वह होगा "foo"
, नहीं "__main__"
, और यह if
कथन के शरीर को छोड़ देगा ।
हमेशा
- यह
"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")
if __name__ == "__main__":
ब्लॉक की स्थिति को अजगर 3 के रूप में दूर किया गया है / बाधित किया गया है? मैंने पाया है कि कुछ जानकारी बताते हुए।