اذهب إلى المحتوى

السؤال

نشر

رأيت اليوم كود يستخدم جملة with للتعامل مع الملفات لكن لم أفهم ما الذي تفعله هذه الجملة ولماذا تم استعمالها، لذلك لدي بعض الأسئلة حولها:

  • ما هو إستخدام هذه الجملة؟ وما هي الصيغة syntax الصحيحة لاستعمالها؟
  • هل يوجد خطر في استخدام هذه الجملة؟ وهل يمكنني أن أستعمل جملة try … except بدلًا منها
  • ما هي المكتبات / الأصناف / الدوال القياسية التي يمكنني استخدامها معها؟ (مثل دالة open على سبيل المثال)

Recommended Posts

  • 0
نشر
  • يمكنك استخدام with في ال error handling و ال management resources غالباً في بث الملفات حيث تستخدم في عدة عمليات مرتبطة ومترتبة على بعضها ويمكنك استخدامها كالتالي
 with open('file.txt', 'w') as f:
     f.write('hello')

في هذه الحالة لا تحتاج لاستخدام f.close فهي تقوم بذلك بدلاً عنك

  • بالطبع لا مشكلة في استخدام with بل اعد الأفضل في بعض الإستخدامات يمكنك بالطبع استخدام try  except بدلاً منها ولكن with توفر عليك بعض المهام وإختصار للكود
  • حتى تستطيع استخدام with يجب توفير الدعم لها من خلال إنشاء Context Manager على هيئة كائن حتى يتواجد الدوال __enter__ و __exit__  لتستطيع العمل ب with هناك العديد من الدوال والمكتبات التي بدأت توفير الدعم للعمل ب with 
  • 0
نشر

في بايثون الكلمة المحجوزة with تستخدم عند التعامل مع الموارد غير المُدارة مثل file streams 

إنه يسمح لك بالتأكد من أن المَورد تم تنظيفه عندما يكون الكود الذي استخدمه انتهى من عمله

حتى إذا ظهرت إستثناءات exceptions فيمكنك إستخدام try/finally لمعالجة الإستثناء

وايضاً with تتأكد من أن عملية file stream لا تقوم بحظر العمليات الأخرى إذا ظهر إستثناء 

إذا أردت فتح وقراءة ملف ستستخدم الكود التالي

file = open('file-path', 'w') 
try: 
    file.write('Lorem ipsum') 
finally: 
    file.close()

لكن مع with ستحصل على كود أكثر نظافة كالآتي

with open('file-path', 'w') as file: 
    file.write('Lorem ipsum') 

كما في الكود السابق ، مع with تم تبسيط الكود الى سطرين فقط

يمكنك إستخدام with مع عمليات الطلب من قواعد البيانات ايضاً كما يلي

def get_all_users():
    with sqlite3.connect('db/users.db') as connection:
        cursor = connection.cursor()
        cursor.execute("SELECT * FROM users ORDER BY id desc")
        all_users = cursor.fetchall()
        return all_users

 

  • 0
نشر

1- تستخدم with في لغة البرمجة بايثون لexception handling وذلك لتفادى توقف البرنامج عن العمل في حالة ظهور خطأ و يجعل ايضاً البرنامج أكثر مقروئية. و تستخدم غالباً للتحكم في حالة التعامل مع الذاكرة أو المعالج streaming لانها تتأكد من أن كل ما تم إستخدامه في البرنامج تم إغلاقه release resources.

2- مثال لبرنامج بإستخدام with و بدون إستخدامها في حالة فتح ملف للكتابة:

file = open('myfile', 'w')
file.write('hello world!')
file.close()

في البرنامج السابق فتحنا الملف المعرف بmyfile وقمنا بكتابة العبارة hello world! بداخله ثم قفلنا الملف، و الان يمكننا تنفيذ نفس المثال و لكن بإستخدام try except كالتالي:

file = open('myfile', 'w')
try:
    file.write('hello world!')
except:
    file.close()

والان يمكننا أن نستخدم with بالطريقة التالية:

with open('myfile', 'w') as file:
	file.write('hello world!')

لاحظ أننا لم نقم بعملية قفل الملف التي تتكفل بها عبارة with إذ أن الملف يتم قفله و تحرير كل مساحة تم إستخدامها في الذاكرة بعد الإستخدام مباشرة. أي عملية خطأ تحدث في عملية الكتابة تدخلنا في تنفيذ الجزء الخاص بexcept وقد لا يتم قفل الملف بصورة صحيحة و التي يعتمد عليها معظم التعديلات في الملف.

3- نعم لا مانع من إستخدام العبارة with لانها تؤدي نفس غرض try except لكن مع الميزات الإضافية التي تم ذكرها في 1 و 2.

4- لعلك لاحظت عزيزي @Fahmy Mostafa أن العبارة with تستخدم مع الstreaming، لذلك يمكنك التفكير في الأحوال التي تحتاج فيها إرسال و إستقبال البيانات إما محلياً بالتعامل مع ملفات موجودة بالجهاز كفتح ملف للقراءة و الكتابة، والتعامل مع قواعد البيانات كالمثال الموضح في شرح @عبدالمجيد الجرادي، أو إستقبال و إرسال بيانات خارجياً عن طريق الإنترنت مثلاً. يمكنك مراجعة موقع بايثون للتعرف على streams أكثر.

 

  • 1
نشر

تم تقديم عبارة with لأول مرة منذ خمس سنوات، في Python 2.5.
تُستخدم with عند العمل مع موارد غير مُدارة "unmanaged resources" مثل file streams  Open network connections. Unmanaged memory ومع الأقفال Locks و ال sockets وال subprocesses.
 يسمح لك بالتأكد من "تنظيف" المورد عند انتهاء تشغيل الكود الذي يستخدمه، حتى إذا تم طرح استثناءات.
ففي حال استخدمتها مع الملفات فتتمثل ميزة استخدام عبارة with في ضمان إغلاق الملف بشكل آمن بغض النظر عن كيفية الخروج من الكتل البرمجية المتداخلة الموجودة لديك. بحيث إذا حدث استثناء قبل نهاية الكتلة البرمجية،  فسيتم إغلاق الملف بشكل مسبق بواسطة معالج استثناء خارجي. وإذا كانت الكتلة المتداخلة تحتوي على تعليمة return ، أو تعليمة continue أو break، فإن تعليمة with ستغلق الملف تلقائياً في تلك الحالات أيضاً. حيث تضمن عبارة with نفسها بالحصول على الموارد وتحريرها بالشكل المناسب.
يكون استخدامها مفيداً عندما يكون لديك عمليتان مترابطتان ترغب في تنفيذهما كزوج،  مع وجود كتلة من التعليمات البرمجية بينهما. المثال الكلاسيكي هو فتح ملف ومعالجة الملف ثم إغلاقه وهذا ماسنراه في المثال التالي:

# وبدون معالجة للاستثناءات التي قد تحدث with بدون استخدام 
f = open('path', 'w')
f.write('hsoub')
f.close()
# مع معالجة للاستثناءات التي قد تحدث with بدون استخدام 
f = open('path', 'w')
try:
    f.write('hsoub')
finally:
    f.close()
#with استخدام 
with open('path', 'w') as file:
    f.write('hsoub')

في أول مثال قد يؤدي حدوث استثناء أثناء استدعاء write إلى عدم إغلاق الملف بشكل سليم مما يؤدي إلى حدوث العديد من الأخطاء في الكود.
الطريقة الثانية في المثال أعلاه تهتم بجميع الاستثناءات ولكن استخدام تعليمة with يجعل الكود مضغوطاً وقابل للقراءة بشكل أكبر. وبالتالي ، تساعد العبارة في تجنب الأخطاء والتسريبات من خلال ضمان تحرير المورد بشكل صحيح عند تنفيذ التعليمات البرمجية التي تستخدم المورد بالكامل. ولاحظ أنك لن تحتاج لتعليمة close كما في أول حالتين.
يمكنك أيضاً استخدام تعليمة with مع كائنات معرفة من قبلك حيث يمكن استخدامها في الكائنات التي يحددها المستخدم وهذا مفيد بالنسبة لك لأن دعم عبارة with في العناصر الخاصة بك سيضمن عدم ترك أي مورد مفتوحًا أبدًا.
لاستخدامها مع الكائنات المعرفة من قبل المستخدم، تحتاج فقط إلى إضافة التوابع __enter __ () و __exit __ () في الكائن، مثال:

class wr(object):
    def __init__(self, file_name):
        self.file_name = file_name
    def __enter__(self):
        self.file = open(self.file_name, 'w')
        return self.file
    def __exit__(self):
        self.file.close()
#مع الكائن  with استخدام التعليمة 
with wr('file.txt') as f:
    f.write('hasoub')

إن الكلمة المفتاحية with تشكل باني ل wr، وبمجرد وصول التنفيذ لتعليمة with يتم إنشاء كائن من wr، ثم يقوم بايثون باستدعاء التابع enter الذي يقوم بتهيئة المورد الذي تريد أن تستخدمه في ال object الخاص بك، ويجب أن تقوم طريقة __enter __ () دائمًا بإرجاع واصف للمورد "descriptor"(مقبض للوصول للملف) الذي تم الحصول عليه.
يتم استخدام f للإشارة لل descriptor الذي تم الحصول عليه من التابع enter، ويتم وضع الكود البرمجي الذي يستخدم المورد بداخل كتلة with وبمجرد تنفيذ الكود الموجود داخل الكتلة with ، يتم استدعاء طريقة __exit __ () ليتم تحرير جميع الموارد.
# وهذا ليس كل شيء عن تعليمة with.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...