8.7. تعريف إجراءات التنظيف #
تحتوي عبارة try على عبارة اختيارية أخرى مُخصصة لتحديد إجراءات التنظيف التي يجب تنفيذها في جميع الظروف. على سبيل المثال:
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
في حال وجود عبارة finally، سيتم تنفيذها كآخر مهمة قبل اكتمال عبارة try. تُنفّذ عبارة finally سواءً أنتجت عبارة try استثناءً أم لا. تناقش النقاط التالية حالات أكثر تعقيدًا عند حدوث استثناء:
- إذا حدث استثناء أثناء تنفيذ جملة try، فيمكن معالجة الاستثناء بجملة except. إذا لم تُعالج جملة except الاستثناء، يُعاد تشغيل الاستثناء بعد تنفيذ جملة final.
- يمكن أن يحدث استثناء أثناء تنفيذ جملة except أو else. مرة أخرى، يُعاد تشغيل الاستثناء بعد تنفيذ جملة final.
- إذا وصلت جملة try إلى جملة break أو continue أو return، فسيتم تنفيذ جملة final قبل تنفيذ جملة break أو continue أو return مباشرةً.
- إذا تضمنت جملة final جملة return، فستكون القيمة المُعادة هي قيمة جملة return لجملة final، وليست قيمة جملة return لجملة try.
على سبيل المثال:
>>> def bool_return():
... try:
... return True
... finally:
... return False
...
>>> bool_return()
False
مثال أكثر تعقيدًا:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
كما ترى، يتم تنفيذ جملة “finally” في جميع الأحوال. لا تتم معالجة خطأ النوع الناتج عن قسمة سلسلتين نصيتين بواسطة جملة “except”، وبالتالي يُعاد طرحه بعد تنفيذ جملة “finally”.
في التطبيقات العملية، تُعد جملة “finally” مفيدة لتحرير الموارد الخارجية (مثل الملفات أو اتصالات الشبكة)، بغض النظر عن نجاح استخدام المورد.
8.8. إجراءات التنظيف المحددة مسبقًا #
تُحدد بعض الكائنات إجراءات تنظيف قياسية ليتم تنفيذها عند عدم الحاجة إلى الكائن، بغض النظر عن نجاح العملية التي تستخدمه أو فشلها. انظر إلى المثال التالي، الذي يحاول فتح ملف وطباعة محتوياته على الشاشة.
for line in open("myfile.txt"):
print(line, end="")
تكمن مشكلة هذه الشيفرة في أنها تترك الملف مفتوحًا لفترة زمنية غير محددة بعد انتهاء تنفيذ هذا الجزء من الشيفرة. هذه ليست مشكلة في النصوص البرمجية البسيطة، ولكنها قد تُشكل مشكلة في l
تطبيقات arger. تسمح عبارة with باستخدام كائنات مثل الملفات بطريقة تضمن تنظيفها دائمًا بسرعة وبشكل صحيح.
with open("myfile.txt") as f:
for line in f:
print(line, end="")
بعد تنفيذ العبارة، يُغلق الملف f دائمًا، حتى في حال مواجهة مشكلة أثناء معالجة الأسطر. الكائنات التي توفر، مثل الملفات، إجراءات تنظيف محددة مسبقًا ستشير إلى ذلك في وثائقها.