سؤال

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

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

المحلول

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

نصائح أخرى

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

try:
    lock.acquire()
    # do stuff
finally:
    lock.release()

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

lock.acquire()
try:
    # do stuff
finally:
    # If lock.acquire() fails, this *doesn't* run
    lock.release()

باستخدام أ with بيان ، يصبح من المستحيل أن يخطئ هذا ، لأنه مدمج في مدير السياق:

with lock: # The lock *knows* how to correctly handle acquisition and release
  # do stuff

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

للحصول على أمثلة قصيرة ، لا يبدو هذا كربح كبير ، لكنه يحدث فرقًا كبيرًا عند مراجعة التعليمات البرمجية. عندما أرى lock.acquire() في قطعة من الكود ، أحتاج إلى التمرير لأسفل والتحقق من ذلك lock.release(). عندما أرى with lock:, ، على الرغم من عدم الحاجة إلى هذا الشيك - يمكنني أن أرى على الفور أن القفل سيتم إصداره بشكل صحيح.

هناك اثني عشر مثال على استخدام with في PEP343, ، بما في ذلك مثال فتح الملف:

  1. يتم إصدار قالب لضمان قفل ، تم الحصول عليه في بداية الكتلة ، عند ترك الكتلة
  2. قالب لفتح ملف يضمن إغلاق الملف عند ترك الكتلة
  3. قالب لارتكاب معاملة قاعدة بيانات أو إعادة ترحيلها
  4. مثال 1 إعادة كتابة بدون مولد
  5. إعادة توجيه stdout مؤقتا
  6. متغير في فتح () الذي يعيد أيضًا حالة خطأ
  7. مثال آخر مفيد هو عملية تمنع الإشارات
  8. استخدام آخر لهذه الميزة هو السياق العشري
  9. إليك مدير سياق بسيط للوحدة العشرية
  10. مدير سياق "إغلاق الكائن" العام
  11. سياق تم إصداره () لإصدار قفل تم الحصول عليه مسبقًا مؤقتًا عن طريق تبديل مكالمات الاستحواذ () و REFER ()
  12. مدير سياق "متداخل" يقوم تلقائيًا بوشك السياقات الموردة من اليسار إلى اليمين لتجنب المسافة البادئة المفرطة
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top