يجب أن أسمي إغلاق () بعد urllib.urlopen ()؟
سؤال
أنا جديد في بيثون وقراءة رمز شخص آخر:
ينبغي urllib.urlopen()
يتبعها urllib.close()
ب خلاف ذلك، فإن المرء سوف تسرب الاتصالات، صحيح؟
المحلول
ال close
يجب أن يتم استدعاء الطريقة نتيجة من urllib.urlopen
, ليس على ال urllib
الوحدة نفسها كما كنت تفكر في (كما ذكرت urllib.close
- أي غير موجود).
أفضل نهج: بدلا من x = urllib.urlopen(u)
إلخ، استخدم:
import contextlib
with contextlib.closing(urllib.urlopen(u)) as x:
...use x at will here...
ال with
بيان، و closing
مدير السياق، سيضمن الإغلاق المناسب حتى في وجود استثناءات.
نصائح أخرى
مثل PPERT يقول، سوف تصبح عناوين URL خارج النطاق مؤهلة لجمع القمامة.
ومع ذلك، لاحظ ذلك أيضا urllib.py
يحدد:
def __del__(self):
self.close()
هذا يعني ذاك عندما يصل عدد المرجع لهذا المثيل إلى الصفر, ، إنه __del__
سيتم استدعاء الطريقة، وبالتالي close
سيتم استدعاء الطريقة كذلك. أكثر الطرق "الطبيعية" لعدد المرجع للوصول إلى الصفر هي ببساطة السماح للمثيل في الخروج من النطاق، ولكن لا يوجد شيء يمنعك بصرامة من صريح del x
في وقت مبكر (ومع ذلك لا يدعو مباشرة __del__
ولكن فقط يقلل من عدد المرجع من قبل واحد).
إنه بالتأكيد نمط جيد لإغلاق مواردك بشكل صريح - خاصة عندما يدير طلبك خطر استخدام الكثير من الموارد المذكورة - ولكن بايثون إرادة تنظف تلقائيا لك إذا لم تفعل أي شيء مضحك مثل الحفاظ على المراجع (التعميم؟) المراجع إلى المثيلات التي لا تحتاج إليها بعد الآن.
بالتحدث بدقة، هذا صحيح. ولكن في الممارسة العملية، مرة واحدة (إذا) urllib
يخرج النطاق، سيتم إغلاق الاتصال من قبل جامع القمامة التلقائي.
أنت أساسا فعل تحتاج إلى إغلاق اتصالك صراحة عند استخدام ironpython.. وبعد يعتمد الإغلاق التلقائي على الخروج من النطاق على مجموعة القمامة. ركضت في وضع لا يعمل فيه جمع القمامة لفترة طويلة من أن ويندوز نفد من المقابس. كنت أقترب خادم الويب بتردد مرتفع (أي ارتفاع كأرضي ويسمح للاتصال، ~ 7 هرتز). أستطيع أن أرى "الاتصالات المعمول بها" (أي مآخذ الاستخدام المستخدمة) ترتفع وما فوق perfmon. كان الحل للاتصال gc.collect()
بعد كل مكالمة إلى urlopen
.