python - ماذا لو كان __name__ == "__main__": هل؟


ماذا تفعل if __name__ == "__main__": هل؟

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while 1:
        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))



Answers


عندما يقرأ مترجم بايثون ملف المصدر، فإنه ينفذ كافة التعليمات البرمجية الموجودة فيه.

قبل تنفيذ التعليمات البرمجية، فإنه سيتم تعريف عدد قليل من المتغيرات الخاصة. على سبيل المثال، إذا كان مترجم بيثون يقوم بتشغيل تلك الوحدة النمطية (ملف المصدر) كبرنامج رئيسي، فإنه يحدد المتغير __name__ الخاص أن يكون لها قيمة "__main__" . إذا تم استيراد هذا الملف من وحدة نمطية أخرى، فسيتم تعيين __name__ على اسم الوحدة النمطية.

في حالة النص البرمجي، لنفترض أنه ينفذ كدالة رئيسية، على سبيل المثال قلت شيئا من هذا القبيل

python threading_example.py

على سطر الأوامر. بعد إعداد المتغيرات الخاصة، فإنه سيتم تنفيذ بيان import وتحميل تلك الوحدات. ثم سيتم تقييم كتلة def إنشاء كائن دالة وإنشاء متغير يسمى myfunction يشير إلى كائن الدالة. وبعد ذلك سوف تقرأ البيان __name__ وترى أن __name__ لا يساوي "__main__" ، لذلك سيتم تنفيذ كتلة أظهرت هناك.

أحد أسباب القيام بذلك هو أنه في بعض الأحيان كنت أكتب وحدة نمطية (ملف .py ) حيث يمكن تنفيذها مباشرة. بدلا من ذلك، فإنه يمكن أيضا استيرادها واستخدامها في وحدة نمطية أخرى. من خلال القيام الاختيار الرئيسي، هل يمكن أن يكون هذا الرمز تنفيذ فقط عندما تريد تشغيل وحدة كبرنامج وليس تنفيذها عندما يريد شخص ما فقط لاستيراد الوحدة النمطية الخاصة بك واستدعاء وظائف نفسك.

انظر هذه الصفحة للحصول على بعض التفاصيل الإضافية.




عندما يتم تشغيل البرنامج النصي بتمريره كأمر إلى مترجم بايثون،

python myscript.py

يتم تنفيذ كافة التعليمات البرمجية التي هي في مستوى البادئة 0. يتم تعريف الوظائف والطبقات التي تم تعريفها، بشكل جيد، ولكن لا يتم تشغيل أي من التعليمات البرمجية الخاصة بهم. على عكس اللغات الأخرى، لا توجد وظيفة main() يتم تشغيلها تلقائيا - الدالة main() هي ضمنا كل الشفرة في المستوى الأعلى.

في هذه الحالة، رمز المستوى الأعلى هو كتلة إف. __name__ هو متغير مضمن الذي يقوم بتقييم اسم الوحدة النمطية الحالية. ومع ذلك، إذا تم تشغيل وحدة نمطية مباشرة (كما هو الحال في myscript.py أعلاه)، __name__ تعيين __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__ .




أبسط تفسير للمتغير __name__ ( __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__'] في هذه الوحدة النمطية إلى اسم الوحدة النمطية.

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

كما ترون، عندما يتم تنفيذ ملف، بيثون يضع globals()['__name__'] في هذا الملف إلى "__main__" .




ماذا تفعل if __name__ == "__main__": هل؟

المتغير العالمي، __name__ ، في الوحدة النمطية التي هي نقطة الدخول إلى البرنامج الخاص بك، هو '__main__' .

لذلك، رمز في هذا if كتلة سوف تعمل فقط إذا كانت هذه الوحدة هي نقطة الدخول إلى البرنامج الخاص بك.

لماذا نحتاج هذا؟

تطوير واختبار التعليمات البرمجية

لنفترض أنك تكتب نص برمجي بيثون مصمم لاستخدامه كنموذج:

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

هل يمكن اختبار وحدة بإضافة هذه الدعوة من وظيفة إلى أسفل:

do_important()

وتشغيله (على موجه الأوامر) مع شيء مثل:

~$ python important.py

المشكلة

ومع ذلك، إذا كنت تريد استيراد الوحدة النمطية إلى نص برمجي آخر:

import important

عند الاستيراد، سيتم استدعاء الدالة do_important ، لذلك ربما كنت التعليق خارج مكالمتك من وظيفة في الأسفل. وبعد ذلك سيكون لديك لتذكر ما إذا كنت قد علقت خارج مكالمة وظيفة الاختبار الخاص بك. وهذا التعقيد الإضافي يعني أنك من المرجح أن تنسى، مما يجعل عملية التنمية الخاصة بك أكثر مزعجة.

طريقة أفضل

__name__ المتغير __name__ إلى مساحة الاسم حيثما يكون مترجم بيثون يحدث في الوقت الحالي. داخل وحدة المستوردة، انها اسم تلك الوحدة. ولكن داخل الوحدة الأساسية (أو جلسة تفاعلية بيثون، أي قراءة مترجم، إيفال، برينت لوب، أو ريبل) تقوم بتشغيل كل شيء من "__main__" .

لذلك إذا تحققت قبل تنفيذ:

if __name__ == "__main__":
    do_important()

مع ما سبق، سيتم تنفيذ الشفرة فقط عند تشغيلها باعتبارها الوحدة الأساسية (أو الاتصال بها عمدا من نص برمجي آخر).

حتى أفضل طريقة

هناك طريقة بيثونيك لتحسين على الرغم من ذلك.

ماذا لو أردنا تشغيل هذه العملية من خارج الوحدة النمطية؟ إذا وضعنا التعليمات البرمجية التي نريد أن تمارس ونحن نطور واختبار في وظيفة مثل هذا ثم قم '__main__' ل '__main__' مباشرة بعد:

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

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

لدينا الآن وظيفة نهائية لنهاية لدينا وحدة نمطية التي سيتم تشغيلها إذا قمنا بتشغيل وحدة باعتبارها الوحدة الأساسية. وسوف تسمح وحدة ووظائفها والطبقات ليتم استيرادها إلى البرامج النصية الأخرى دون تشغيل الوظيفة main ، وسوف تسمح أيضا وحدة (ووظائفها وفئات) ليتم استدعاؤها عند تشغيل من وحدة '__main__' مختلفة، أي

import important
important.main()

ويمكن أيضا العثور على هذا المصطلح في وثائق بايثون في شرح للوحدة __main__ . وينص هذا النص على ما يلي:

تمثل هذه الوحدة النطاق (خلاف ذلك مجهول) الذي ينفذ فيه البرنامج الرئيسي للمترجم - الأوامر قراءة إما من المدخلات القياسية، من ملف نصي، أو من موجه تفاعلي. ومن هذه البيئة التي الاصطلاحية "السيناريو المشروط" ستانزا يسبب سيناريو لتشغيل:

if __name__ == '__main__':
    main()



if __name__ == "__main__" هو الجزء الذي يتم تشغيله عند تشغيل البرنامج النصي من ( python myscript.py ) سطر الأوامر باستخدام أمر مثل python myscript.py .




ماذا 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()



عندما تكون هناك بيانات معينة في وحدتنا ( M.py )، نريد أن يتم تنفيذها عندما سيتم تشغيلها على أنها الرئيسية (غير المستوردة)، في هذه الحالة يمكننا وضع تلك البيانات (حالات الاختبار، بيانات الطباعة) تحت هذا إذا كتلة. كما هو افتراضيا (عند تشغيل وحدة __name__ رئيسي، غير مستورد) يتم تعيين المتغير __name__ إلى "__main__" ، وعندما يتم استيراده المتغير __name__ سوف تحصل على قيمة مختلفة، على الأرجح اسم وحدة ( 'M' ). وهذا مفيد في تشغيل مختلف المتغيرات من وحدات معا، وفصل البيانات الخاصة بها المدخلات والمخرجات وأيضا إذا كان أي حالات الاختبار.

باختصار ، استخدم هذا " if __name__ == "main" " لمنع تشغيل (معينة) التعليمات البرمجية عند استيراد الوحدة النمطية.




دعونا ننظر إلى الإجابة بطريقة أكثر تجريدا:

لنفترض أن لدينا هذا الرمز في x.py:

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

يتم تشغيل كتل A و B عند تشغيل "x.py".

ولكن يتم تشغيل الكتلة A فقط (وليس B) عند تشغيل وحدة نمطية أخرى، "y.py" على سبيل المثال، حيث يتم استيراد زي ويتم تشغيل الشفرة من هناك (كما هو الحال عندما تكون الدالة في "x.py" هي دعا من y.py).




عند تشغيل بيثون بشكل تفاعلي يتم تعيين المتغير __name__ المحلي قيمة __main__ . وبالمثل، عند تنفيذ وحدة نمطية بيثون من سطر الأوامر، بدلا من استيرادها إلى وحدة نمطية أخرى، يتم تعيين سمة __name__ قيمة __main__ بدلا من الاسم الفعلي للوحدة النمطية. وبهذه الطريقة، يمكن للوحدات أن تنظر إلى قيمتها __name__ الخاصة بها لكي تحدد لنفسها كيف يتم استخدامها، سواء كدعم لبرنامج آخر أو __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.



الكثير من مختلف يأخذ هنا على ميكانيكا التعليمات البرمجية في السؤال، "كيف"، ولكن بالنسبة لي أي من ذلك جعلت من المنطقي حتى فهمت "لماذا". وينبغي أن يكون هذا مفيدا بشكل خاص للمبرمجين الجدد.

خذ هذا المثال:

ملف "ab.py":

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

الملف الثاني "xy.py":

import ab
def main():
    print('main function')
def x(): 
    print ('s')
x()
if __name__ == "__main__":
    main()

ما هو هذا الرمز فعليا؟

عند تنفيذ xy.py، يمكنك استيراد ab . يقوم بيان الاستيراد بتشغيل الوحدة على الفور عند الاستيراد، لذلك يتم تنفيذ عمليات أب قبل ما تبقى من زي. بمجرد الانتهاء مع أب، فإنه يستمر مع زي.

المترجم بتتبع البرامج النصية التي تعمل مع __name__ . عندما تقوم بتشغيل البرنامج النصي - بغض النظر عن ما كنت قد سمته - المترجم يسميها "__main__" . هذه هي الطريقة التي يحتفظ بها البرنامج النصي الذي هو الملف الرئيسي، البرنامج النصي الذي يحصل عاد إلى بعد مكالمة خارجية إلى برنامج نصي آخر. (النص "المنزل"، قد تقول.) يتم تعيين أي نص آخر يسمى من هذا البرنامج الرئيسي 'الرئيسي' اسم الملف باسم __name__ . وبالتالي، فإن الخط if __name__ == "__main__": هو اختبار المترجم لتحديد ما إذا كان يعمل على البرنامج النصي الذي يبحث في (تحليل)، أو إذا كان يتطلع مؤقتا إلى برنامج نصي آخر. وهذا يعطي مبرمج المرونة لجعل البرنامج النصي تتصرف بشكل مختلف إذا كان يسمى خارجيا.

لفهم ما يحدث، ركز أولا على الخطوط غير المترابطة والترتيب الذي تظهر به في النصوص البرمجية. تذكر أن وظيفة - أو def - كتل لا تفعل أي شيء في حد ذاته حتى يتم استدعاؤهم. ما قد يفكر فيه المترجم إذا ما تخلل نفسه:

  • افتح xy.py. حسنا، xy.py هو ملف 'الوطن'؛ وهذا يعني أنه يحصل يسمى "__main__" في المتغير __name__ .
  • استيراد ملف مفتوح مع __name__ ab.py.
  • أوه، وظيفة. سوف اتذكر ذلك.
  • أوك، فونكتيون a ()؛ تعلمت ذلك للتو. أعتقد أنني سوف طباعة الآن.
  • نهاية الملف؛ العودة إلى "__main__" !
  • أوه، وظيفة. سوف اتذكر ذلك.
  • واحدة أخرى.
  • الدالة x ()؛ موافق، الطباعة 'ق'.
  • ما هذا؟ بيان إف. حسنا، تم استيفاء الشرط (تم تعيين المتغير __name__ إلى "__main__" )، لذلك سوف أدخل الوظيفة main() وطباعة 'الوظيفة الرئيسية'.

السطرين السفليين يعني: "إذا كان هذا هو" الرئيسي "أو المنزل النصي، تنفيذ وظيفة تسمى main() ، لهذا السبب سترى def main(): كتلة الأعلى، الذي يحتوي على تدفق الرئيسي من البرنامج النصي وظائف.

لماذا تنفيذ هذا؟

تذكر ما قلته في وقت سابق عن بيانات الاستيراد؟ عند استيراد وحدة نمطية أنها لا مجرد 'التعرف' عليه والانتظار لمزيد من التعليمات - فإنه يدير في الواقع جميع العمليات القابلة للتنفيذ الواردة في البرنامج النصي. لذلك، وضع اللحم الخاص بك في النص main() وظيفة الحجر الصحي بشكل فعال ذلك، ووضعه في عزلة بحيث لن يتم تشغيل على الفور عند استيرادها من قبل برنامج نصي آخر.

مرة أخرى، سوف تكون هناك استثناءات، ولكن الممارسة الشائعة هي أن main() لا عادة ما تسمى خارجيا. لذلك قد تتساءل شيئا واحدا آخر: إذا كنا لا ندعو main() ، لماذا نحن ندعو السيناريو على الإطلاق؟ فذلك لأن الكثير من الناس ينظمون نصوصهم مع الوظائف المستقلة التي يتم بناؤها ليتم تشغيلها بأنفسهم. ثم يتم استدعاؤهم فيما بعد في مكان آخر في جسم النص. الذي يقودني إلى هذا:

ولكن يعمل رمز دون ذلك

نعم هذا صحيح. يمكن استدعاء هذه الوظائف المنفصلة من نص برمجي في سطر غير موجود داخل دالة main() . إذا كنت معتادا (كما أنا، في مراحل التعلم المبكر من البرمجة) لبناء النصوص في الخط الذي يفعل بالضبط ما تحتاجه، وسوف تحاول معرفة ذلك مرة أخرى إذا كنت في حاجة من أي وقت مضى هذه العملية مرة أخرى .. ، حسنا، أنت لا تستخدم لهذا النوع من البنية الداخلية إلى التعليمات البرمجية، لأنه أكثر تعقيدا لبناء وانها ليست بديهية للقراءة. ولكن هذا هو السيناريو الذي ربما لا يمكن أن يكون وظائفها تسمى خارجيا، لأنه إذا فعل ذلك سيبدأ حساب وتعيين المتغيرات. وهناك احتمالات إذا كنت تحاول إعادة استخدام وظيفة، ويرتبط النص الجديد الخاص بك عن كثب بما فيه الكفاية إلى القديم الذي يمكن أن يكون هناك متغيرات متضاربة.

أود أن أقول كما جانبا، وهذا الموضوع يحتوي على إجابة من قبل كيندال التي ساعدتني أخيرا لفهم - لماذا، وليس كيف. لسوء الحظ تم وضع علامة عليه كنسخة مكررة من هذا واحد ، والذي أعتقد أنه خطأ.




بوت سيمبلي __name__ هو متغير محدد لكل برنامج نصي، يحدد ما اذا كان البرنامج النصي يتم تشغيله كنموذج رئيسي أو يتم تشغيله كنموذج مستورد.

حتى إذا كان لدينا اثنين من البرامج النصية.

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

و؛

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

الإخراج من تنفيذ البرنامج النصي 1 هو؛

Script 1's name: __main__

والناتج من تنفيذ البرنامج النصي 2 هو؛

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

كما ترى؛ __name__ يخبرنا أي رمز هو وحدة 'الرئيسي'. هذا شيء عظيم لأنه يمكنك كتابة التعليمات البرمجية فقط وليس لديك ما يدعو للقلق حول القضايا الهيكلية كما هو الحال في C / C ++، حيث، إذا كان ملف لا تنفذ وظيفة 'الرئيسية' ثم لا يمكن تجميعها باعتبارها قابلة للتنفيذ وإذا كان يفعل ذلك لا يمكن بعد ذلك أن تستخدم كمكتبة.

لنفترض أنك تكتب نصا ثعبانيا يفعل شيئا عظيما وتنفذ حمولة من الوظائف المفيدة لأغراض أخرى، إذا أردت استخدامها، يمكنني فقط استيراد النص البرمجي واستخدامها بدون تنفيذ البرنامج (نظرا لأن التعليمات البرمجية لا تنفذ إلا ضمن if __name__ == "__main__": السياق). في حين أنه في C / C ++ سيكون لديك لجزء من تلك القطع في وحدة منفصلة التي تتضمن بعد ذلك الملف. صورة الوضع أدناه.

الأسهم هي روابط الاستيراد. لثلاث وحدات كل محاولة لتشمل التعليمات البرمجية وحدات السابقة هناك ستة ملفات (تسعة، عد ملفات التنفيذ) وخمس وصلات، وهذا يجعل من الصعب إدراج رمز آخر في مشروع أس ما لم يتم تجميعها على وجه التحديد كمكتبة. الآن صورة لثعبان.

يمكنك كتابة وحدة نمطية، إذا كان هناك شخص يريد استخدام التعليمات البرمجية الخاصة بك أنها مجرد استيراده و متغير __name__ يمكن أن تساعد على فصل جزء قابل للتنفيذ من البرنامج من جزء المكتبة.




وهو خاص عندما يتم استدعاء ملف بيثون من سطر الأوامر. يتم استخدام هذا عادة لاستدعاء دالة "الرئيسي ()" أو تنفيذ التعليمات البرمجية بدء التشغيل المناسبة الأخرى مثل وسيطات سطر الأوامر التعامل معها على سبيل المثال.

ويمكن أن يكتب في عدة طرق، وآخر هو:

def main():
    dosomething()


__name__ == '__main__' and main()

أنا لا أقول يجب عليك استخدام هذا في رمز الإنتاج، لكنه يخدم لتوضيح أنه لا يوجد شيء "السحرية" حول if __name__ == '__main__' . انها اتفاقية (عظيم!) لاستدعاء وظيفة رئيسية في ملفات بايثون.




if __name__ == "__main__":
    main()

تحقق من أن السمة __name__ للنص البرمجي الثعبان هي "__main__". وبعبارة أخرى، إذا تم تنفيذ البرنامج نفسه، فإن السمة تكون __main__، لذلك سيتم تنفيذ البرنامج (في هذه الحالة الوظيفة الرئيسية ()).

ومع ذلك، إذا كان يتم استخدام البرنامج النصي الثعبان من قبل وحدة نمطية، سيتم تنفيذ أي رمز خارج بيان إف، حتى إذا تم استخدام __name__ == "__main__" فقط للتحقق مما إذا كان البرنامج يستخدم وحدة نمطية أم لا، وبالتالي يقرر سواء لتشغيل التعليمات البرمجية.




هناك عدد من المتغيرات التي يوفرها النظام (مترجم بيثون) لملفات المصدر (الوحدات النمطية). يمكنك الحصول على قيمها في أي وقت تريد، لذلك، دعونا نركز على متغير __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__ لن تساوي " رئيسي " في تلك الحالة بالذات.

نأمل أن يساعد هذا.




إذا كان __name__ == "__main__": هو في الأساس بيئة النصي الأعلى مستوى، فإنه يحدد المترجم أن ('لدي أعلى أولوية ليتم تنفيذها أولا').

'__main__ ' هو اسم النطاق الذي ينفذ فيه كود المستوى الأعلى. يتم تعيين اسم الوحدة النمطية مساويا ل ' الرئيسية ' عند القراءة من المدخلات القياسية، والنصي، أو من موجه تفاعلي.

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



أعتقد أنه من الأفضل كسر الإجابة بعمق وبكلمات بسيطة:

__name__ : لكل وحدة نمطية في بيثون سمة خاصة تسمى __name__ . وهو متغير المضمنة التي ترجع اسم الوحدة النمطية.

__main__ : مثل لغات البرمجة الأخرى، بيثون أيضا لديه نقطة دخول التنفيذ أي الرئيسي. ' الرئيسي ' هو اسم النطاق الذي ينفذ فيه كود المستوى الأعلى. في الأساس لديك طريقتان لاستخدام وحدة بيثون: تشغيله مباشرة كبرنامج نصي، أو استيراده. عندما يتم تشغيل وحدة نمطية كنص برمجي، يتم تعيين __main__ إلى __main__ .

وبالتالي، يتم تعيين قيمة السمة __name__ إلى __main__ عند تشغيل الوحدة كبرنامج رئيسي. وإلا يتم تعيين قيمة __name__ لاحتواء اسم الوحدة النمطية.




print __name__

الإخراج لما سبق هو الرئيسي

if __name == "__main__":
  print direct method

البيان أعلاه هو يحصل صحيح والطباعة طريقة مباشرة لنفترض إذا استوردوا هذه الفئة في فئة أخرى فإنه لا طباعة طريقة مباشرة. لأن بينما استيراد فإنه سيتم تعيين __name__ == "firstmodel name"




يمكنك جعل الملف صالحة للاستعمال كنص، فضلا عن وحدة استيراد .

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




السبب ل

if __name__ == "__main__":
    main()

هو في المقام الأول لتجنب مشاكل قفل الاستيراد التي قد تنشأ عن وجود رمز المستوردة مباشرة .

أحد الآثار الجانبية هو أنك تقوم بتسجيل الدخول تلقائيا إلى منهجية تدعم نقاط دخول متعددة.