كل ما تريد معرفته عن النطاق في Python ، لكنك خجلت من السؤال

تحسبًا لبدء سلسلة محادثات جديدة في الدورة التدريبية "Python Developer" ، قررنا التحدث عن النطاق في Python. ماذا جاء من هذا؟ - اقرأ المواد أدناه.




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

تحدد النطاقات أي جزء من البرنامج يمكننا العمل فيه مع متغير معين ، ومنه يكون المتغير "مخفيًا". من المهم للغاية فهم كيفية استخدام القيم والمتغيرات التي نحتاجها فقط ، وكيفية تصرف مترجم اللغة. سنرى أيضًا كيفية التحايل على القيود المفروضة بواسطة النطاق على الإجراءات ذات المتغيرات. في Python ، يوجد ما يصل إلى 3 نطاقات:

  • محلي
  • عالمي
  • غير محلي

تمت إضافة النطاق الأخير ، غير المحلي في Python 3.

عادة ، نتحدث عن النطاق عندما تكون على دراية بالوظائف. باستخدام مثالهم ، سننظر في عمل نطاق المتغيرات.

النطاق المحلي


خذ بعين الاعتبار وظيفة تعرض some_listعنصر قائمة حسب العنصر:

def print_list(some_list):
    for element in some_list:
        print(element)

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

NameError: name 'element' is not defined


الآن سنقوم بما يلي:

def print_list(some_list):
    for element in some_list:
        print(element) 

element = 'q'
print_list([1, 2, 3])
print(element) 


ونحصل على:

1
2
3
q

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

def print_list(some_list):
    for element in sudden_list:
        print(element) 

sudden_list = [0, 0, 0]
print_list([1, 2, 3])

نتيجة:

0
0
0

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

من المهم التحدث عن الثوابت هنا. لا يوجد فرق لمترجم Python ما تسميه متغيرًا ، لذلك من الأفضل إعادة كتابة الرمز أعلاه على النحو التالي:

SUDDEN_LIST = [0, 0, 0]

def print_list(some_list):
    for element in SUDDEN_LIST:
        print(element) 

print_list([1, 2, 3]) 

الآن كل شيء في مكانه. الشيء هو أنه في Python لا يمكنك تحديد ثابت بشكل ثابت بطريقة ما ككائن لا ينبغي تعديله. لذا فإن الطريقة التي تستخدم بها قيمة متغير مكتوب باسمه بحروف كبيرة تبقى فقط على ضميرك. سؤال آخر هو أنه بهذه الطريقة سيوضح المتغير المسجل لمن يقرأ التعليمات البرمجية أن المتغير لن يتغير في أي مكان. أو على الأقل لا ينبغي.

النطاق العالمي


يحتوي Python على كلمة أساسية globalتسمح لك بتغيير قيمة متغير عام من داخل دالة. هو مكتوب قبل اسم المتغير ، والذي سيتم اعتباره عامًا داخل الوظيفة. كما ترون من المثال ، فإن قيمة المتغير في candyتزايد الآن ، ولاحظ أننا لا نمرره كوسيطة للدالة get_candy().

candy = 5

def get_candy():
    global candy 
    candy += 1
    print('  {} .'.format(candy))
    
get_candy()
get_candy()
print(candy)


نتيجة لذلك ، نحصل على:


	  6 .
  7 .
7


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

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

نطاق غير محلي


ظهر هذا المفهوم في Python 3 مع الكلمة الأساسية nonlocal. منطق كتاباته هو نفس منطق global. ومع ذلك ، nonlocalهناك ميزة. Nonlocalيتم استخدامه غالبًا في الوظائف المتداخلة عندما نريد أن نجعل المترجم يفهم أنه بالنسبة للدالة المتداخلة ، فإن متغيرًا معينًا ليس محليًا ، ولكنه ليس عالميًا بالمعنى العام.

def get_candy():
    candy = 5
    def increment_candy(): 
        nonlocal candy
        candy += 1
        return candy
    return increment_candy
    
result = get_candy()()
print(' {} .'.format(result))

نتيجة:

 6 .

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

في الختام ، يمكن صياغة عدة قواعد:

  1. من داخل الوظيفة توجد متغيرات مرئية تم تعريفها داخلها وخارجها. المتغيرات المحددة داخليا هي محلية وعالمية خارجيا.
  2. خارج الوظائف ، لا توجد متغيرات محددة داخلها مرئية.
  3. , global.
  4. nonlocal , , .

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

أريد أيضًا دعوة الجميع إلى ندوة مجانية عبر الويب من OTUS ، حيث سندرس أداة مثل كتابة تعليق توضيحي في Python: سنناقش أسباب عدم تقدير العديد من الناس لها ، والنظر في عدد من الأمثلة من الممارسة العسكرية عندما يمكن أن يحفظ النوع التوضيحي أو حفظ الموقف. لنتحدث عن كيفية ووقت تنفيذ تدقيق النوع على مشاريعك .

All Articles