الفرق بين المراجعتين لصفحة: «Python/defining clean-up actions»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
سطر 43: سطر 43:
for line in open("myfile.txt"):
for line in open("myfile.txt"):
    print(line, end="")
    print(line, end="")
</syntaxhighlight>مشكلة هذه الشيفرة أنّها تترك الملف مفتوحًا لفترة من الزمن بعد تنفيذها. قد لا يبدو هذا أمرًا مهمًّا في الشيفرات الصغيرة، ولكنّه قد يتسبب في مشاكل كبيرة في التطبيقات الكبيرة. تسمح عبارة <code>with</code> باستخدام الكائنات مثل الملفات بطريقة تضمن التخلّص منها فورًا وبصورة صحيحة.<syntaxhighlight lang="python3">
</syntaxhighlight>مشكلة هذه الشيفرة أنّها تترك الملف مفتوحًا لفترة من الزمن بعد تنفيذها. قد لا يبدو هذا أمرًا مهمًّا في الشيفرات الصغيرة، ولكنّه قد يتسبب في مشاكل كبيرة في التطبيقات الكبيرة. تسمح عبارة <code>with</code> باستخدام الكائنات -مثل الملفات- بطريقة تضمن التخلّص منها فورًا وبصورة صحيحة.<syntaxhighlight lang="python3">
with open("myfile.txt") as f:
with open("myfile.txt") as f:
    for line in f:
    for line in f:

مراجعة 12:38، 18 مايو 2018

تمتلك عبارة try جزءًا اختياريًا آخر، والهدف منه هو تعريف أحداث تنظيف (clean-up actions) يجب تنفيذها في جميع الظروف، فعلى سبيل المثال:

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>

تُنفّذ عبارة finally دائمًا قبل الخروج من عبارة try، سواء أحدث الاستثناء أم لم يحدث. وعند حدوث استثناء في عبارة try ولم تجر معالجته بواسطة عبارة except (أو أنّه حدث في عبارة except أو else) فإنّه يعاد إطلاق ذلك الاستثناء عند تنفيذ عبارة finally. تنفذ عبارة finally أيضًا عند الخروج من عبارة try بواسطة عبارات break، أو continue أو return. فمثلًا:

>>> 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 قد نُفّذت في جميع الحالات في المثال السابق، ولاحظ أيضًا أنّ الاستثناء TypeError الناشئ من قسمة سلسلتين نصيتين على بعضهما البعض لم يُعالج بواسطة عبارة except ولهذا أعيد إطلاقه بعد تنفيذ عبارة finally.

عبارة finally مفيدة في التطبيقات الواقعية عند التخلص من المصادر الخارجية (مثل الملفات أو اتصالات الشبكة) بصرف النظر عما إذا كان ذلك المصدر قد استُخدم في الشيفرة أم لا.

أحداث التنظيف المعرّفة من طرف المستخدم

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

انظر إلى المثال التالي والذي يحاول فتح ملف وطباعة محتوياته على الشاشة:

for line in open("myfile.txt"):
    print(line, end="")

مشكلة هذه الشيفرة أنّها تترك الملف مفتوحًا لفترة من الزمن بعد تنفيذها. قد لا يبدو هذا أمرًا مهمًّا في الشيفرات الصغيرة، ولكنّه قد يتسبب في مشاكل كبيرة في التطبيقات الكبيرة. تسمح عبارة with باستخدام الكائنات -مثل الملفات- بطريقة تضمن التخلّص منها فورًا وبصورة صحيحة.

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

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

مصادر