سؤال

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

هل هناك شيء عن الثعبان الذي يجعل "استخدام صارمة" السلوك غير الضرورية أو خاصة غير مرغوب فيه ؟

بدلا من ذلك, هو "استخدام صارمة" السلوك غير الضرورية في بيرل ، على الرغم من انتشار التبني ؟

ملاحظة:من "الضروري" أعني "عمليا ضروري" ، لم يكن ضروريا.من الواضح أنك يمكن كتابة بيرل دون "استخدام صارمة" ، ولكن (ما رأيت) معظم بيرل المبرمجين هل استخدامه.

ملاحظة:مترجم بايثون-المجمع لا تحتاج تتطلب "استخدام صارمة"-مثل القيود -- هل يمكن استخدام الزائفة pragma مماثلة إلى "استخدام صارمة" التي يتم تجاهلها من قبل العادي مترجم.أنا لا أتحدث عن إضافة اللغة على مستوى الميزة.


تحديث:شرح ما "استخدام صارمة" في بيرل في التعليقات.(رابط المستندات الرسمية في الفقرة الأولى.)

"استخدام صارمة" التوجيه ثلاثة عناصر متميزة ، والتي هي مثيرة للاهتمام حقا:

  • استخدام صارمة فأر:ثابت الشيكات بشكل معجمي راقب متغير الاستخدام في البرنامج الخاص بك.(نضع في اعتبارنا أن في بيثون ، هناك في الأساس فقط global نطاق local نطاق).العديد من بيثون linters التحقق من هذا النوع من الشيء.لأنه هو فقط تحليل ثابت من أنها يمكن أن تفعل ، linters تفترض كنت تستخدم واضحة المعجمية النطاق و تحذيرك من الأشياء التي تظهر الخطأ في هذا المعنى حتى كنت أقول لهم أن تغلق ؛ أي

    FOO = 12
    foo += 3
    

    إذا كنت لا تفعل أي شيء يتوهم مع مساحات هذا يمكن أن يكون مفيدا للتحقق من الأخطاء المطبعية.

  • استخدام صارمة الحكام:يمنع رمزية مساحة dereferencing.بيثون هو الأقرب التناظرية باستخدام locals() و globals() للقيام رمزية ملزمة معرف البحث.

  • استخدام صارمة الغواصات:لا التناظرية الحقيقي في بيثون.

هل كانت مفيدة؟

المحلول

"فلسفة ربط وقت التشغيل التي تتبناها بايثون...يجعل سلوك "الاستخدام الصارم" غير ضروري [و] غير مرغوب فيه بشكل خاص"

ملخص جيد جدًا.شكرًا.

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


يحرر

"أطلب منا أن نتأمل لماذا نحن لسنا بحاجة إليها، ولماذا يعتقد مبرمجو لغة بيرل أنهم بحاجة إليها."

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

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

أنا أكتب Java تقريبًا بقدر ما أكتب Python.التحقق من النوع الثابت في Java لا يمنع أي مشاكل منطقية؛ولا يسهل تلبية متطلبات الأداء؛لا يساعد في تلبية حالات الاستخدام.حتى أنه لا يقلل من حجم اختبار الوحدة.

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

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

انظر إلى أسئلة SO Python الأكثر شيوعًا والمتعلقة باللغة (وليس مجال المشكلة أو المكتبة).

هل هناك فرق بين "foo is لا شيء" و"foo == لا شيء"؟ -- == ضد. is.لا يوجد فحص ثابت يمكن أن يساعد في هذا.انظر أيضا هل هناك فرق بين `==` و`is` في بايثون؟

ماذا تفعل ** (النجمة المزدوجة) و * (النجمة) للمعلمات؟ -- *x يعطي قائمة، **x يعطي القاموس.إذا كنت لا تعرف ذلك، فسيموت برنامجك على الفور عندما تحاول القيام بشيء غير مناسب لتلك الأنواع."ماذا لو لم يفعل برنامجك أي شيء "غير مناسب"'".ثم يعمل برنامجك'قال ناف.

كيف يمكنني تمثيل "Enum" في بايثون؟ - هذا نداء لنوع ما من نوع المجال المحدود.الفصل ذو القيم على مستوى الفصل يقوم بهذه المهمة إلى حد كبير."ماذا لو قام شخص ما بتغيير المهمة".سهل البناء.تجاوز __set__ لرفع الاستثناء.نعم، قد يؤدي الفحص الثابت إلى اكتشاف ذلك.لا، لا يحدث عمليًا أن يرتبك شخص ما بشأن ثابت التعداد والمتغير؛وعندما يحدث ذلك، فمن السهل اكتشافه في وقت التشغيل."ماذا لو لم يتم تنفيذ المنطق أبدًا".حسنًا، هذا تصميم سيئ واختبار وحدة ضعيف.إن ارتكاب خطأ في المترجم ووضع منطق خاطئ لم يتم اختباره مطلقًا ليس أفضل مما يحدث في لغة ديناميكية عندما لا يتم اختبارها مطلقًا.

تعبيرات المولد مقابل.قائمة الفهم - التحقق الثابت لا يساعد في حل هذا السؤال.

لماذا 1+++2 = 3؟ - التحقق الثابت لن يكتشف ذلك.1+++2 في لغة C يعد قانونيًا تمامًا على الرغم من كل عمليات فحص المترجم.إنه ليس نفس الشيء في Python كما هو الحال في C، ولكنه قانوني تمامًا.ومربك تمامًا.

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

نصائح أخرى

حسنًا، أنا لست مبرمجًا للغة بايثون، لكني أقول إن الإجابة هي "نعم".

أي لغة ديناميكية تتيح لك إنشاء متغير بأي اسم في أي وقت، يمكنها استخدام براغما "صارمة".

Strict vars (أحد خيارات الصارمة في Perl، يؤدي "استخدام صارم" إلى تشغيلها جميعًا مرة واحدة) في Perl يتطلب الإعلان عن جميع المتغيرات قبل استخدامها.مما يعني أن هذا الكود:

my $strict_is_good = 'foo';
$strict_iS_good .= 'COMPILE TIME FATAL ERROR';

يولد خطأ فادح في وقت الترجمة.

لا أعرف طريقة لجعل Python يرفض هذا الرمز في وقت الترجمة:

strict_is_good = 'foo';
strict_iS_good += 'RUN TIME FATAL ERROR';

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

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

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

ملحوظة أركز على التأثير العملي لـ stict vars في لغة Perl، وأقوم بتغطية بعض التفاصيل.إذا كنت تريد حقا أن تعرف كل التفاصيل انظر بيرلدوك الصارمة.

تحديث:ردود على بعض التعليقات

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

com.popcnt :أعلم أن لغة بايثون ستؤدي إلى استثناء وقت التشغيل.قلت بنفس القدر.أنا أؤيد تجميع التحقق من الوقت حيثما أمكن ذلك.يرجى إعادة قراءة هذا المنصب.

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

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

لست على دراية كافية بـ pylint و pychecker لأقول ما هي فئات الأخطاء التي سيكتشفونها.كما قلت أنا عديم الخبرة مع بايثون.

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

التحديث 2:

cdleary - من الناحية النظرية، أنا أتفق معك، يمكن للمحلل الثابت القيام بأي عملية تحقق يستطيع المترجم القيام بها.وفي حالة بايثون، ينبغي أن يكون كافيا.

ومع ذلك، إذا كان المترجم الخاص بك معقدًا بدرجة كافية (خاصة إذا كان لديك الكثير من البراغمات التي تغير كيفية حدوث الترجمة، أو إذا كنت مثل Perl، فيمكنك تشغيل التعليمات البرمجية في وقت الترجمة)، فيجب أن يقترب المحلل الثابت من تعقيد المترجم/المترجم إلى قم بالتحليل.

هيه، كل هذا الحديث عن المترجمين المعقدين وتشغيل التعليمات البرمجية في وقت الترجمة يظهر خلفيتي في لغة Perl.

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

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

ربما يكون تبديل سطر الأوامر طريقة أفضل لإضافة التحليل الثابت القسري؛)

(لا أقصد بأي حال من الأحوال الطعن في قدرات بايثون عندما أقول إنها لا تستطيع التعامل مع سلوك وقت الترجمة مثل سلوك بيرل.لدي حدس أن هذا قرار تصميمي مدروس بعناية، وأستطيع أن أرى الحكمة فيه.تعتبر مرونة Perl الشديدة في وقت الترجمة، IMHO، قوة كبيرة وضعفًا رهيبًا في اللغة؛أرى الحكمة في هذا النهج أيضًا.)

لدى Python شيء يمكنه تغيير بناء جملة البرنامج النصي:

from __future__ import print_function

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

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

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

تتم معالجة تغييرات اللغة والمكتبة الأخرى التي لا تتضمن بناء الجملة من خلال تحذيرات نظام.

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

فيما يلي قائمة بما يفعله "الاستخدام الصارم":

  1. يعد استخدام المراجع الرمزية خطأً في وقت التشغيل.هذا يمنعك من القيام بأشياء مجنونة (ولكن في بعض الأحيان مفيدة مثل)

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. يعد استخدام متغيرات غير معلنة خطأً في وقت التشغيل (وهذا يعني أنك بحاجة إلى استخدام "my" أو "our" أو "local" للإعلان عن نطاق المتغير الخاص بك قبل استخدامه.

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

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

لأكون صادقًا، أفتقد النطاق المعجمي الوحيد.الاثنان الآخران سأفكر في الثآليل في بيرل.

هذا الجواب الصحيح ، ولكن لا ربما شرح الوضع بالمعنى العملي.

توجد ثابت أدوات تحليل بايثون لكن وقت الترجمة الشيكات تميل إلى أن تكون >نقيض وقت التشغيل ملزمة فلسفة الثعبان تحتضن.

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

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

Java و C/C++ أعتبر خطوة أخرى إلى الأمام ، مع التحقق من نوع.الدافع هو عملي ، وليس الفلسفي.كيف يمكنك التقاط العديد من الأخطاء ممكن في أقرب وقت ممكن ، تأكد من أنه يمكنك القضاء على كل منهم قبل إطلاق رمز الإنتاج ؟ كل لغة يبدو أن تأخذ استراتيجية معينة و ذلك استنادا إلى ما أعتقد هو المهم.في لغة مثل Perl, حيث وقت التشغيل ملزمة ليس المعتمدة ، فمن المنطقي للاستفادة من "استخدام صارمة" إلى جعل التنمية أسهل.

وأنا أعتبر 'use strict' في بيرل أشبه pragma كما كنت ألمح في:يتغير سلوك مترجم.

Perl لغة الفلسفة يختلف عن الثعبان الفلسفة.كما يتم إعطاء أكثر من ما يكفي من حبل شنق نفسك مرارا وتكرارا في بيرل.

لاري جدار كبير في اللسانيات ، لذلك لدينا من بيرل ما يشار إلى TIMTOWTDI (أقول tim-toe-dee) مبدأ مقابلزن من الثعبان:

يجب أن يكون هناك واحد-- ويفضل أن يكون واحد فقط --طريقة واضحة للقيام بذلك.

يمكنك بسهولة جدا استخدام pylint pisechka إلى الخروج مع الخاصة بك نكهة use strict بايثون (أو شيء مشابه perl -cw *scriptname*) ولكن بسبب فلسفات مختلفة في لغة تصميم, سوف لا تواجه هذه الممارسة على نطاق واسع.

على أساس تعليقك على الملصق الأول, كنت معتادا مع بايثون import this.هناك الكثير من الأمور التي تضيء لماذا لا نرى أي ما يعادل use strict في بيثون.إن التأمل في koan وجدت في زين من بيثون ، قد تجد التنوير لنفسك.:)

لقد وجدت أنني أهتم فقط باكتشاف الإشارات إلى vars غير المعلنة.يحتوي Eclipse على تكامل pylint عبر PyDev، وعلى الرغم من أن pylint أبعد ما يكون عن الكمال، إلا أنه يقوم بعمل معقول في ذلك.

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

ولكن يمكنني أن أرى فائدة بعض الوظائف المشابهة للبيلينت أصبحت متاحة في شكل علامة سطر أوامر.يشبه إلى حد ما رمز التبديل -3 الخاص بـ Python 2.6، والذي يحدد نقاط عدم التوافق بين كود Python 2.x و3.x.

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

تتكون بعض برامج Perl الخاصة بي من 5000 سطر إلى 10000 سطر من التعليمات البرمجية مقسمة إلى عشرات الوحدات.لا يمكن للمرء حقًا القيام ببرمجة الإنتاج دون استخدام "الاستخدام الصارم".لن أسمح أبدًا بتثبيت كود الإنتاج في المصنع بلغات لا تفرض "إعلانات متغيرة".

ولهذا السبب أصبح لدى Perl 5.12.x الآن سلوك "الاستخدام الصارم" باعتباره السلوك الافتراضي.يمكنك إيقاف تشغيلها.

لقد أعطاني PHP عددًا لا بأس به من المشكلات بسبب عدم وجود تطبيق إعلان متغير.لذلك عليك أن تقتصر على البرامج الصغيرة بهذه اللغة.

مجرد رأي...

abcParsing

بيرل هي لغة غير مقيدة كما قالوا :) .لذلك يمكنك استخدام المتغير قبل الإعلان عنه؛على سبيل المثال :إذا كنت تستخدم اسم var "is_array" ولكنك كتبت "is_arrby"، فلن يقوم المترجم بالإبلاغ عن الخطأ بدون "استخدام صارم".لذلك عند ترميز برنامج طويل في بيرل، من الأفضل استخدام عبارة "استخدام صارم".بالطبع، أقل من 50 سطرًا لتشغيل البرنامج النصي لمرة واحدة، ليست هناك حاجة :)

يبدو أن الكود المثالي لـ "Pythonic" يخدم الكثير من نفس الغرض use strict.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top