পাইথন দোভাষী যখনই একটি উত্স ফাইল পড়েন, তখন এটি দুটি কাজ করে:
এটা পছন্দ কয়েক বিশেষ ভেরিয়েবল সেট করে __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"
মডিউল কোড কার্যকর
বিশেষ ভেরিয়েবলগুলি সেট আপ করার পরে, দোভাষা মডিউলটিতে সমস্ত কোড প্রয়োগ করে, একসাথে একটি বিবৃতি। আপনি কোডের নমুনা সহ পাশের অন্য উইন্ডোটি খুলতে চাইতে পারেন যাতে আপনি এই ব্যাখ্যাটি অনুসরণ করতে পারেন।
সর্বদা
এটি স্ট্রিং মুদ্রণ করে "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
আপনার স্ক্রিপ্টের মতো ফাইলগুলি আমদানি করে এবং বিশেষ পরীক্ষার ফাংশনগুলি চালিয়ে কাজ করে। আপনি চান না যে এটি স্ক্রিপ্টটি চালানোর চেষ্টা করুন কারণ এটি মডিউলটি আমদানি করে।
আপনার মডিউলটি বেশিরভাগই মূল প্রোগ্রাম হিসাবে ব্যবহৃত হয় তবে এটি উন্নত ব্যবহারকারীদের জন্য একটি প্রোগ্রামার-বান্ধব এপিআই সরবরাহ করে।
এই উদাহরণগুলির বাইরেও, এটি মার্জিত যে পাইথনে স্ক্রিপ্ট চালানো কেবল কয়েকটি ম্যাজিক ভেরিয়েবল সেটআপ করে স্ক্রিপ্ট আমদানি করছে। স্ক্রিপ্ট "চালানো" স্ক্রিপ্টের মডিউল আমদানির একটি পার্শ্ব প্রতিক্রিয়া।
চিন্তার জন্য খাদ্য
# 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 পর্যন্ত ব্লক শর্তটি কি অবচিত / অপ্রচলিত হয়েছে? আমি উল্লেখ করে কিছু তথ্য পেয়েছি।