المسافة البادئة في Python - خيار الحل

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

يبدو أنه في حالة Python ، مثل هذه العملية غير ممكنة.

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


المقدمة


عزيزي القارئ!
إذا كانت العبارة قريبة منك:
1) أن البرمجة هي فن رفيع.
2) أنه عند البرمجة بأي لغة تحتاج إلى الاستفادة القصوى من قوة وتنوع هذه اللغة لتقليل شفرة المصدر.
3) أنه عند البرمجة ، تحتاج إلى إظهار مستواك العالي في شفرة المصدر للبرنامج بحيث لا يمكن لأحد أن يقول عن برنامجك أنه "غبي".

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

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

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

العيوب الرئيسية لـ Python:

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

2) Python بطيء ومترابطة (GIL - Global Interpreter Lock).

3) في Python ، تستند كتل البرنامج فقط (!) على المسافة البادئة. و لهذا:

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

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

العيب الثاني في Python هو أن لديها قابلية تشغيل ممتازة ثنائية الاتجاه مع C / C ++.

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

وللعيب الثالث لبايثون ، أود أن أقدم حلا خاصا بي.

تعلمون جميعًا أنه بالنسبة للغالبية العظمى من اللغات ، غالبًا ما يتم استخدام التنسيق التلقائي للنص المصدر.

أولئك. بغض النظر عن المسافة البادئة التي تتم كتابة البرنامج بهذه اللغة ، عند بدء التنسيق التلقائي ، سيتم وضع كل المسافة البادئة في شكلها القياسي. بالنسبة لبايثون ، يبدو هذا مستحيلاً.

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

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

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

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

حل مشكلة المسافة البادئة في بايثون


تتكون المسافة البادئة في Python من الأوامر التالية:

- class
- def

- for
- while

- if

- try

- with

ولإزالة الاعتماد على المسافة البادئة ، قررت لكل من هذه الأوامر جعلها قاعدة لاستخدام الأمر "النهائي" ، الذي سيؤدي بالتأكيد إلى إغلاق كتلة الأوامر (المسافة البادئة).

أوامر الفئة والدفاع


لأوامر class / def ، عادة لا توجد مشكلة في إكمال كتلة المسافة البادئة ، مثل تم إغلاق الكتلة باستخدام الأمر class / def الجديد.

الحالة الوحيدة هي وجود برنامج فرعي واحد أو أكثر معلن داخل برنامج فرعي / أسلوب آخر.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
    ...  ppg_1 ...

ثم ، إذا قمت عن طريق الخطأ بتحويل مجموعة التعليمات الخاصة بالبرنامج الفرعي الداخلي الأخير ، فسوف يتم دمجها مع أوامر البرنامج الفرعي / الطريقة التي يتم فيها الإعلان عن هذا البرنامج الفرعي الداخلي.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_1 ...

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

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
        return
    ...  ppg_1 ...

أوامر for و while


في نهاية عبارات "for" و "while" ، تحتاج إلى وضع "متابعة".

أولئك. سيبدو الأمر على النحو التالي:

for  <...> :             #  
    ...  ....
    continue             #  

و

while  <...> :           #  
    ...  ....
    continue             #  

على سبيل المثال:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

        ...  ...

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

إليك الطريقة:
        ...  ...

        for i in range(10):
            ...  for ...

        ...  for  ...

        ...  for  ...

        ...  ...

وفي المثال أدناه ، سيؤدي حذف المسافة البادئة بطريق الخطأ إلى ظهور خطأ على الفور:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

            continue

        ...  ...

إذا الأمر


في نهاية عبارة "if" ، تحتاج إلى وضع الأمر "elif 0: pass" ، وبدلاً من "else" ، استخدم الأمر "elif 1:".

أولئك. لـ "if" سيكون هناك كتلة كاملة من الأوامر:

if <>                      #  
    ...  ....
elif <>
    ...  ....
elif 1:                    #  "else"
    ...  ....
elif 0: pass               #  

على سبيل المثال:
        ...  ...

        if  result != -1 :

            ...  if ...

            ...  if ...

            ...  if ...

        elif 0: pass

        ...  ...

إذا قمت بعملها كما هو موضح أعلاه ، فعندئذٍ في كتلة الأمر "if ... elif 0: pass" ، ستؤدي المسافة البادئة إلى ظهور خطأ في بدء التشغيل.

بدون "elif 0: pass" ، إذا تم حذف المسافات البادئة في السطور الأخيرة من كتلة "if" عن طريق الخطأ ، ستبحث أولاً عن المكان الذي تسبب في بدء البرنامج بشكل غير متوقع في العمل بشكل غير صحيح ، ثم التفكير في المسافات البادئة التي يجب أن تكون في الكتلة وأي - لا.
        ...  ...

        if  result != -1 :

            ...  if ...

        ...  if ...

        ...  if ...

        ...  ...

لماذا ، في رأيي ، من المستحسن إغلاق كتل الأوامر التي أنشأها المشغلون "لـ" ،
"while" ، "if" ، إلخ ...

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

ثم ستسمح لك الإنشاءات التي تحتوي على "متابعة" و "elif 0: pass" ، بالإضافة إلى الحماية من الحذف غير المقصود ، بالإشارة إلى الكتلة التي بدأت بها وكتابة تعليق عليها.

على سبيل المثال ، ترى نهاية كتلة كبيرة:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

ومن الصعب تذكر ما يعنيه كل مستوى مسافة بادئة.

لكن الأمر أسهل بكثير عندما يبدو مثل هذا:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                            continue    #   b'\\r\\n'   

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                    elif 0: pass     #  " "  " "

                elif 0: pass         #   . - 

                continue             #    

            continue                 #  .,  -  " "
                      
    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

جرب الأمر


هناك تشابه كامل مع "إذا".

try:                   #  
    ...  ....
except <...>:
    ...  ....
except 1:              #  "else"
    ...  ....
except 0: pass         #  

المشكلة الوحيدة هي في النهاية: الأمر . بعد ذلك ، لم يعد بإمكانك وضع أي من أوامر كتلة المحاولة الحالية.

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

أولئك. سيكون النص مع "أخيرًا" كما يلي:

    def my_ppg():
        ...
        return

    ...

    finally:
        my_ppg()

    ...

في هذه الحالة ، يمكنك أيضًا تطبيق التنسيق التلقائي بأمان ولا تخشى
حذف المسافات البادئة عن طريق الخطأ.

أمر "مع"


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

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

استنتاج



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

الآن ، بابتسامة ، نطرح سؤالًا مثل هذا: "ما هي عيوب Python إذا قمت بتنسيق كتل المسافة البادئة بشكل صحيح ، والتفاعل مع C / C ++ إذا لزم الأمر ، وعدم استخدام Python في تطبيقات الهاتف المحمول والحيوية؟"

الجواب: "فقط عيوب طفيفة. أولئك. وعلى العموم - لا ".

وبهذه الصيغة للسؤال ، يمكننا فقط الاستمتاع بالمزايا الرئيسية لـ Python.

  1. بساطة.
  2. الحد الأدنى من دورة اختبار المواقع: تم تدقيقها - تدقيقها.
  3. السلطة - مكتبات / أطر عمل Python "لكل ذوق ولون".

هذه المزايا الثلاثة تعطي ، في رأيي ، نسخة شبه كاملة من اللغة (لا تنس أن هذا لا يخضع إلا للشروط المحددة في السؤال أعلاه!).

All Articles