سؤال

أنا جديد في بيثون وقراءة رمز شخص آخر:

ينبغي 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.

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