__Name__ == "__ মেইন__": কি করলে?


6053

নিম্নলিখিত কোড দেওয়া, কি করে 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 পর্যন্ত ব্লক শর্তটি কি অবচিত / অপ্রচলিত হয়েছে? আমি উল্লেখ করে কিছু তথ্য পেয়েছি।
কার্লোসওয়াম 85

1
@ carloswm85 এটি সত্য নয়।
জর্গোস মাইরিয়ানথাস

উত্তর:


6629

পাইথন দোভাষী যখনই একটি উত্স ফাইল পড়েন, তখন এটি দুটি কাজ করে:

  • এটা পছন্দ কয়েক বিশেষ ভেরিয়েবল সেট করে __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.pypython 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')অজগর স্ক্রিপ্টে চালিত হলে কী হবে ? আমি মনে করি যে আমি নিজে নিজে যখন সেমিডিতে টাইপ করব ঠিক তখনই এটি foo_barশুরু করা হবে । এটাই কি? @ এমআরফুজের উত্তরটি অ্যাকাউন্টে নিলে এটি করতে এবং আমার পছন্দ মতো একসাথে অনেকগুলি "মূল" মডিউল থাকা কোনও সমস্যা হবে না। এমনকি মান পরিবর্তন করা বা বেশ কয়েকটি স্বতন্ত্রভাবে দৃষ্টান্ত তৈরি করে (বা উদাহরণস্বরূপ একে অপরকে তৈরি করেছে ) একে অপরের সাথে আলাপচারিতা পাইথনের জন্য যথারীতি ব্যবসা হওয়া উচিত। আমি কি কিছু মিস করছি? __name__ = '__main__'foo_bar.py__name__subprocess
হাজেফ

12
@ হাইজেফ জিনিসগুলি কীভাবে কাজ করবে সে সম্পর্কে আপনি সঠিক subprocess.run। এটি বলেছিল, স্ক্রিপ্টগুলির মধ্যে ভাগ করে নেওয়ার একটি সর্বোত্তম উপায় হ'ল মডিউল তৈরি করা এবং স্ক্রিপ্টগুলি একে অপরকে স্ক্রিপ্ট হিসাবে আহ্বান না করে ভাগ করা মডিউলগুলি কল করা। subprocess.runকলগুলি ডিবাগ করা শক্ত কারণ বেশিরভাগ ডিবাগারগুলি প্রক্রিয়া সীমানা
ছাড়িয়ে না যায়

4
আমার চিন্তার বিভাগের জন্য খাবারে foo2.py উদাহরণে সন্দেহ আছে f foo2.py আমদানি ফাংশনবি থেকে কী হয়? আমার দৃষ্টিতে এটি কেবল ফাংশনবি থেকে foo2.py আমদানি করে
user471651

1
@ এমআরফুজ আমি কখনই এই এক্সডি এর মতো কিছু করার ইচ্ছা করিনি এটি আমার মনে এসেছিল এবং আমি বুঝতে পেরেছিলাম যে সম্ভবত পিপিএলকে সহায়তা করার জন্য এটি আশ্চর্যজনক ধারণা ছিল। এই ধরণের জিনিসগুলি সম্পর্কে তাদের মন মোড়ানো। @ user471651 from foo2 import functionBফাংশনবি থেকে কেন foo2 আমদানি করা উচিত ? এটি একটি শব্দার্থক বিকৃতি। from module import methodমডুল থেকে পদ্ধতিটি আমদানি করে।
হাজেফ

2
আপনার কোডটি আমদানি করতে পারে এমন একটি মডিউল হ'ল multiprocessingবিশেষত উইন্ডোজে এই পরীক্ষাটি প্রয়োজনীয় করে তোলা।
ইয়ান ভার্নিয়ার

1798

যখন আপনার স্ক্রিপ্টটি পাইথন ইন্টারপ্রেটারের কাছে কমান্ড হিসাবে পাঠানো হবে,

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

এটি সম্পর্কে চিন্তা করার এই
পদ্ধতিটির

719

__name__পরিবর্তনশীল (ইমো) এর সহজ ব্যাখ্যা নিম্নলিখিত:

নিম্নলিখিত ফাইল তৈরি করুন।

# 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__"?
হাই 15

83

কি করে if __name__ == "__main__":?

__name__একটি গ্লোবাল ভেরিয়েবল (পাইথনে, গ্লোবাল আসলে মডিউল স্তরের মানে ) যা সমস্ত নেমস্পেসে বিদ্যমান। এটি সাধারণত মডিউলটির নাম (একটি strপ্রকার হিসাবে )।

তবে মাইকোডি.পি-র মতো পাইথন প্রক্রিয়াটি যা চালায় তা একমাত্র বিশেষ কেস হিসাবে:

python mycode.py

অন্যথায় বেনামী বিশ্বব্যাপী নামস্থান মান নির্ধারিত হয় '__main__'তার থেকে __name__

সুতরাং, চূড়ান্ত লাইন সহ

if __name__ == '__main__':
    main()
  • আপনার মাইকোড.পি স্ক্রিপ্টের শেষে,
  • এটি যখন প্রাথমিক, এন্ট্রি-পয়েন্ট মডিউল যা পাইথন প্রক্রিয়া দ্বারা চালিত হয়,

আপনার স্ক্রিপ্টের অনন্যভাবে সংজ্ঞায়িত mainফাংশনটি চালিত করবে cause

এই কনস্ট্রাক্টটি ব্যবহার করার আরেকটি সুবিধা: আপনি নিজের কোডটি অন্য স্ক্রিপ্টের মডিউল হিসাবে আমদানি করতে পারেন এবং তারপরে এবং যখন আপনার প্রোগ্রামটি সিদ্ধান্ত নেয় তবে মূল ফাংশনটি চালাতে পারেন:

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__":হ'ল প্রাথমিকভাবে সম্পাদিত 'হোম' স্ক্রিপ্টটির ব্যাখ্যা / বিশ্লেষণ করছে বা এটি অস্থায়ীভাবে অন্য কোনও (বহিরাগত) স্ক্রিপ্টে উঁকি দিচ্ছে কিনা তা নির্ধারণ করার জন্য দোভাষীর পরীক্ষা। এটি প্রোগ্রামারকে স্ক্রিপ্টটিকে ভিন্নভাবে আচরণ করার জন্য স্বতন্ত্রতা দেয় যাতে এটি সরাসরি বনাম বলা হয় exec

আসুন কী ঘটছে তা বোঝার জন্য উপরের কোডটি ধাপে প্রথমে আনইনডেন্ট করা রেখাগুলি এবং স্ক্রিপ্টগুলিতে সেটির ক্রমটি প্রদর্শিত হয় সেটির দিকে দৃষ্টি নিবদ্ধ রাখুন। এই ফাংশনটি মনে রাখবেন - বা def- ব্লকগুলি কল না করা পর্যন্ত তারা নিজেরাই কিছু করেন না। দোভাষী যদি নিজের কাছে ডুবে থাকে তবে কী বলতে পারে:

  • Xy.py কে 'হোম' ফাইল হিসাবে খুলুন; সেটিতে কল "__main__"মধ্যে __name__পরিবর্তনশীল।
  • আমদানি করুন এবং এর সাথে ফাইল খুলুন __name__ == "ab.py"
  • ওহ, একটি ফাংশন। আমি এটা মনে রাখব।
  • ঠিক আছে, ফাংশন a(); আমি এটা শিখেছি। ' অ্যাব ফাইলে ইন ফাংশন ' মুদ্রণ করা হচ্ছে ।
  • ফাইলের সমাপ্তি; ফিরে "__main__"!
  • ওহ, একটি ফাংশন। আমি এটা মনে রাখব।
  • আরেকটা.
  • কার্য x(); ঠিক আছে, মুদ্রণ ' পেরিফেরিয়াল টাস্ক: অন্যান্য প্রকল্পে কার্যকর হতে পারে '।
  • এটা কী? একটি ifবিবৃতি। ঠিক আছে, শর্তটি পূরণ করা হয়েছে (ভেরিয়েবলটি __name__সেট করা হয়েছে "__main__"), সুতরাং আমি main()ফাংশনটি প্রবেশ করবো এবং ' মূল ফাংশন: এটি এখানে কর্ম ' প্রিন্ট করব ।

নীচের দুটি লাইনটির অর্থ: "যদি এটি "__main__"বা 'হোম' স্ক্রিপ্ট হয় তবে ডাকা ফাংশনটি সম্পাদন করুন main()। এ কারণেই আপনি def main():শীর্ষে একটি ব্লক আপ দেখতে পাবেন , এতে স্ক্রিপ্টটির কার্যকারিতাটির মূল প্রবাহ রয়েছে।

কেন এটি বাস্তবায়ন?

আমদানির বিবৃতি সম্পর্কে আমি আগে যা বলেছিলাম তা মনে আছে? আপনি যখন কোনও মডিউল আমদানি করেন এটি কেবল এটি "সনাক্ত" করে না এবং পরবর্তী নির্দেশের জন্য অপেক্ষা করে - এটি আসলে স্ক্রিপ্টের মধ্যে থাকা সমস্ত নির্বাহযোগ্য ক্রিয়াকলাপ চালায়। সুতরাং, আপনার স্ক্রিপ্টের মাংস main()কার্যকরভাবে ফাংশনে রেখে এটি পৃথক করে রাখা যাতে এটি অন্য স্ক্রিপ্ট দ্বারা আমদানি করার সাথে সাথে তত্ক্ষণাত্ চলতে না পারে।

আবার, ব্যতিক্রম হবে, তবে সাধারণ অনুশীলন হ'ল main()সাধারণত বাহ্যিকভাবে ডাকা হয় না। সুতরাং আপনি আরও একটি বিষয় ভাবতে পারেন: আমরা যদি কল না দিই main(), কেন আমরা স্ক্রিপ্টটি মোটেই কল করছি ? এটি কারণ যে অনেকে তাদের স্ক্রিপ্টগুলি স্ট্যান্ডেলোন ফাংশনগুলির সাথে কাঠামো করেন যা ফাইলের বাকী কোডের চেয়ে স্বতন্ত্রভাবে চালিত হওয়ার জন্য নির্মিত হয়। এগুলি পরে স্ক্রিপ্টের শিরোনামে অন্য কোথাও ডাকা হয়। যা আমাকে এনেছে:

কোডটি এটি ছাড়া কাজ করে

হ্যা, তা ঠিক. এই পৃথক ফাংশনগুলি কোনও ইন-লাইন স্ক্রিপ্ট থেকে কল করা যেতে পারে যা কোনও main()ফাংশনের অভ্যন্তরে নেই। যদি আপনি অভ্যস্ত হন (যেমন আমি, প্রোগ্রামিংয়ের আমার প্রাথমিক শিক্ষার পর্যায়ে) অন-লাইন স্ক্রিপ্টগুলি তৈরি করতে যা আপনার যা প্রয়োজন ঠিক তা করে এবং আপনি যদি আবার কখনও সেই অপারেশনটির প্রয়োজন হয় তবে আপনি এটি আবার বের করার চেষ্টা করবেন .. ভাল, আপনি আপনার কোডের জন্য এই জাতীয় অভ্যন্তরীণ কাঠামোর অভ্যস্ত নন, কারণ এটি নির্মাণ করা আরও জটিল এবং এটি পড়ার মতো স্বজ্ঞাত নয়।

তবে এটি এমন একটি স্ক্রিপ্ট যার সম্ভবত এটির ফাংশনগুলি বহিরাগতভাবে বলা যেতে পারে না, কারণ এটি যদি তা করে তা অবিলম্বে ভেরিয়েবলগুলি গণনা এবং নির্ধারণ শুরু করে। এবং সম্ভাবনাগুলি হ'ল যদি আপনি কোনও ফাংশন পুনরায় ব্যবহার করার চেষ্টা করছেন, আপনার নতুন স্ক্রিপ্টটি পুরানোটির সাথে যথেষ্ট ঘনিষ্ঠভাবে সম্পর্কিত যা বিরোধী ভেরিয়েবলগুলি থাকতে পারে।

স্বতন্ত্র ফাংশনগুলি বিভক্ত করার ক্ষেত্রে, আপনি আপনার পূর্ববর্তী কাজগুলি অন্য স্ক্রিপ্টে কল করে পুনরায় ব্যবহারের ক্ষমতা অর্জন করবেন। উদাহরণস্বরূপ, "উদাহরণ x().py" "xy.py" "xy.py" থেকে 'x' ফাংশনটি ব্যবহার করে "xy.py" এবং কল আমদানি করতে পারে । (সম্ভবত এটি প্রদত্ত পাঠ্য স্ট্রিংয়ের তৃতীয় শব্দকে মূলধন করছে; সংখ্যার একটি তালিকা থেকে একটি নুমপি অ্যারে তৈরি করে এবং স্কোয়ারিং; বা 3 ডি পৃষ্ঠকে অবনমিত করছে The সম্ভাবনাগুলি সীমাহীন))

(হিসাবে একটি সরাইয়া, এই প্রশ্নের @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__)

এক্সিকিউট করা স্ক্রিপ্ট 1 থেকে আউটপুট

Script 1's name: __main__

এবং স্ক্রিপ্ট 2 সম্পাদন করে আউটপুট হয়:

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

আপনি দেখতে পাচ্ছেন, __name__কোন কোডটি 'মেন' মডিউল। এটি দুর্দান্ত, কারণ আপনি কেবল কোড লিখতে পারেন এবং সি / সি ++ এর মতো কাঠামোগত সমস্যা সম্পর্কে চিন্তা করতে হবে না, যেখানে কোনও ফাইল যদি 'মেন' ফাংশনটি প্রয়োগ করে না তবে এটি এক্সিকিউটেবল হিসাবে সংকলিত হতে পারে না এবং যদি তা করে, এটি তখন গ্রন্থাগার হিসাবে ব্যবহার করা যায় না।

বলুন যে আপনি একটি পাইথন স্ক্রিপ্ট লিখেছেন যা দুর্দান্ত কিছু করে এবং আপনি অন্যান্য কাজের জন্য কার্যকর যে ফাংশনগুলির একটি বোট লোড প্রয়োগ করেন। যদি আমি সেগুলি ব্যবহার করতে চাই তবে আমি কেবল আপনার স্ক্রিপ্ট আমদানি করতে পারি এবং আপনার প্রোগ্রামটি সম্পাদন না করেই তাদের ব্যবহার করতে পারি (আপনার কোডটি কেবল if __name__ == "__main__":প্রসঙ্গের মধ্যে কার্যকর করে)। যদিও সি / সি ++ এ আপনাকে সেই টুকরাগুলি আলাদা মডিউলে ভাগ করতে হবে যাতে তারপরে ফাইলটি অন্তর্ভুক্ত থাকে। নীচের পরিস্থিতি চিত্র;

জটিল ইন সি আমদানি

তীরগুলি লিংকগুলি আমদানি করে। তিনটি মডিউলগুলির জন্য প্রতিটি পূর্ববর্তী মডিউল কোড অন্তর্ভুক্ত করার চেষ্টা করছে সেখানে ছয়টি ফাইল রয়েছে (নয়টি, বাস্তবায়নকারী ফাইলগুলি গণনা করা) এবং পাঁচটি লিঙ্ক। এটি অন্য কোডকে সি প্রকল্পে অন্তর্ভুক্ত করা কঠিন করে তোলে যদি না এটি নির্দিষ্ট করে একটি গ্রন্থাগার হিসাবে সংকলিত হয়। পাইথনের জন্য এখন এটি চিত্র:

পাইথনে মার্জিত আমদানি

আপনি একটি মডিউল লেখেন, এবং যদি কেউ আপনার কোড ব্যবহার করতে চান তবে তারা কেবল এটি আমদানি করে এবং __name__ভেরিয়েবল প্রোগ্রামের নির্বাহযোগ্য অংশটি লাইব্রেরির অংশ থেকে আলাদা করতে সহায়তা করতে পারে।


2
সি / সি ++ চিত্রটি ভুল: একই ইউনিটের 3 বার ( ফাইল 1 )।
নেকড়ে

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
snur

27

if __name__ == '__main__'এটি সম্পর্কে কোনও ব্যাখ্যা দেওয়ার আগে এটি কী __name__এবং কী করে তা বোঝা গুরুত্বপূর্ণ ।

কী __name__?

__name__এটি একটি ডন্ডারআলিয়াস - এটি একটি বৈশ্বিক পরিবর্তনশীল হিসাবে বিবেচনা করা যেতে পারে (মডিউলগুলি থেকে অ্যাক্সেসযোগ্য) এবং একইভাবে কাজ করে 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__ফাইলটির নাম নেয়। প্রকৃত মডিউল বা প্যাকেজ পাথের পাথ দেওয়া হয় নি, তবে এর নিজস্ব ডান্ডারআলিয়া রয়েছে __file__, এটি এটির জন্য অনুমতি দেয়।

আপনার এটি দেখতে __name__হবে, যেখানে এটি প্রধান ফাইল (বা প্রোগ্রাম) সর্বদা ফিরে আসবে __main__, এবং এটি যদি মডিউল / প্যাকেজ বা অন্য কিছু পাইথন স্ক্রিপ্টের বাইরে চলেছে তবে ফাইলটির নাম সেখানে ফিরে আসবে it থেকে উদ্ভূত হয়েছে।

অনুশীলন করা:

পরিবর্তনশীল হওয়ার অর্থ হ'ল এর মানটি ওভাররাইট করা যেতে পারে ("ক্যান" এর অর্থ "উচিত" হওয়া উচিত নয়), এর ওভাররাইটিংয়ের __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 '__main__' শীর্ষ স্তরের কোড সম্পাদন করে এমন সুযোগের নাম । মূলত আপনার কাছে পাইথন মডিউল ব্যবহারের দুটি উপায় রয়েছে: এটিকে সরাসরি স্ক্রিপ্ট হিসাবে চালান, বা এটি আমদানি করুন। মডিউলটি যখন স্ক্রিপ্ট হিসাবে চালানো __name__হয় তখন সেট করা থাকে __main__

সুতরাং, মডিউলটি যখন প্রধান প্রোগ্রাম হিসাবে চালিত __name__হয় __main__তখন বৈশিষ্ট্যের মান সেট করা হয়। অন্যথায় এর মানটি __name__ মডিউলের নাম ধারণ করে সেট করে।


23

কমান্ড লাইন থেকে পাইথন ফাইল কল করার জন্য এটি বিশেষ It এটি সাধারণত "মেইন ()" ফাংশন বলার জন্য বা অন্য প্রারম্ভিক কোডটি কার্যকর করতে ব্যবহৃত হয়, যেমন কমান্ডলাইন আর্গুমেন্ট উদাহরণস্বরূপ পরিচালনা করে।

এটি বিভিন্ন উপায়ে লেখা যেতে পারে। আরেকটি হ'ল:

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
ফ্লো কন্ট্রোল মেকানিজম হিসাবে বুলিয়ান অপারেটরদের শর্ট-সার্কিট আচরণকে শোষণ করা খারাপ স্টাইল কিনা তা এই প্রশ্নটি বাদ দিয়ে, আরও বড় সমস্যা হ'ল এটি প্রশ্নের কোনও উত্তর দেয় না
মার্ক আমেরিকা

@ মার্কআমেরি হাহাহা, শীশ, এখন তা ঘটে। 😊
অধ্যাপক ফ্যালকেন চুক্তি

19

সিস্টেম (পাইথন ইন্টারপ্রেটার) উত্স ফাইলগুলি (মডিউল) সরবরাহ করে এমন বেশ কয়েকটি ভেরিয়েবল রয়েছে। আপনি যে কোনও সময় তাদের মানগুলি পেতে পারেন, সুতরাং, আসুন আমরা __ নাম__ ভেরিয়েবল / বৈশিষ্ট্যটির দিকে ফোকাস করি :

পাইথন যখন একটি সোর্স কোড ফাইল লোড করে, এটি এতে পাওয়া সমস্ত কোডই কার্যকর করে। (দ্রষ্টব্য যে এটি ফাইলে সংজ্ঞায়িত সমস্ত পদ্ধতি এবং ফাংশনকে কল করে না, তবে এটি তাদের সংজ্ঞায়িত করে))

দোভাষী যদি উত্স কোড ফাইলটি কার্যকর করেন আগে, এটি সেই ফাইলের জন্য কয়েকটি বিশেষ ভেরিয়েবল সংজ্ঞায়িত করে; __ নাম__ হ'ল সেই বিশেষ ভেরিয়েবলগুলির মধ্যে একটি যা পাইথন প্রতিটি উত্স কোড ফাইলের জন্য স্বয়ংক্রিয়ভাবে সংজ্ঞায়িত করে।

পাইথন যদি এই উত্স কোড ফাইলটিকে মূল প্রোগ্রাম হিসাবে লোড করে (যেমন আপনার চালিত ফাইল), তবে এটি এই ফাইলটির জন্য "__main__" মান রাখার জন্য বিশেষ __name__ ভেরিয়েবল সেট করে ।

যদি এটি অন্য মডিউল থেকে আমদানি করা হয়, __name__ module মডিউলটির নামে সেট করা হবে।

সুতরাং, আপনার উদাহরণে অংশে:

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 এর কারণে, আপনি এটিকে আমদানি করার সময় সমস্ত কিছু "এ" তে চালিত হতে নাও চান

  3. পয়েন্ট ২-এ সমস্যাটি সমাধান করতে অজগর আপনাকে একটি শর্ত পরীক্ষা করতে দেয় to

  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 নম্বরে! বাকিটি কেবল মৌলিক যুক্তি is


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
@ ওল্ফ: অবশ্যই আমি একাধিক এন্ট্রি পয়েন্ট পদ্ধতি সম্পর্কে কয়েকটি বাক্য যুক্ত করেছি।
ব্যক্তিগত_ক্লাউড

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 ফাইলগুলি দ্বারা আমদানি করা হয় তবে "if বিবৃতি" এর অধীনে কোডটি কার্যকর করা হবে না।

যদি এই .পি python this_py.pyশেল অধীনে চালিত হয় , বা উইন্ডোজে ডাবল ক্লিক করা হয়। "if স্টেটমেন্ট" এর অধীনে কোডটি কার্যকর করা হবে।

এটি সাধারণত পরীক্ষার জন্য লেখা হয়।


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 চালনা করেন তবে if __name__ == "__main__"ফাইল A এ মিথ্যা হয়ে যায়, তাই এটি মুদ্রণ করে আপনি আমাকে দেখতে পারবেন না


5

সমস্ত উত্তর কার্যকারিতা বেশ সুন্দরভাবে ব্যাখ্যা করেছে। তবে আমি এর ব্যবহারের একটি উদাহরণ দেব যা ধারণাটি আরও পরিষ্কার করতে সহায়তা করবে।

ধরে নিন যে আপনার কাছে দুটি পাইথন ফাইল রয়েছে, এপি এবং বি.পি. এখন, a.py b.py আমদানি করে আমরা a.py ফাইল চালাই, যেখানে "ইম্পোর্ট b.py" কোডটি প্রথমে কার্যকর করা হয়। বাকি a.py কোডটি চলার আগে, b.py ফাইলের কোডটি অবশ্যই পুরোপুরি চলতে হবে।

বি.পি. কোডে কিছু কোড রয়েছে যা সেই ফাইল বিপিপি-র সাথে একচেটিয়া এবং আমরা চালানোর জন্য অন্য কোনও ফাইল (বি.পি.পি. ফাইল ব্যতীত) চাই না, যা চালানোর জন্য বি.পি.পি ফাইল আমদানি করেছে।

সুতরাং কোড চেক এই লাইন কি। যদি কোডটি চলমান মূল ফাইল (যেমন, b.py) হয়, যা এই ক্ষেত্রে এটি (a.py মূল ফাইলটি চলমান) না হয় তবে কেবল কোডটি কার্যকর করা হয়।


4

একটি ফাইল তৈরি করুন, এপি :

print(__name__) # It will print out __main__

__name____main__এই ফাইলটি সরাসরি চালিত হওয়ার সাথে সর্বদা সমান হয় এটি দেখায় যে এটি প্রধান ফাইল।

একই ডিরেক্টরিতে অন্য ফাইল, b.py তৈরি করুন :

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__"ব্লকের আগে কোনও কোড (পার্শ্ব প্রতিক্রিয়া ছাড়াই সংজ্ঞা ব্যতীত) স্থান নেয় না । প্রযুক্তিগতভাবে সম্পাদিত স্ক্রিপ্টের শীর্ষস্থানীয়টি হল প্রোগ্রামটির এন্ট্রি পয়েন্ট।
চার্লি হার্ডিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.