Jannah Theme License is not validated, Go to the theme options page to validate the license, You need a single license for each domain name.

كيفية استخدام دالة open في Python لقراءة وكتابة الملفات

8 طرق لاستخدام دالة open() في Python

تُعد دالة open() من أكثر الأدوات استخدامًا في لغة Python، فهي المفتاح الأساسي للتعامل مع الملفات سواء لقراءتها أو كتابتها أو تعديلها. بفضل بساطتها ومرونتها، يمكن للمبرمجين تنفيذ العديد من العمليات على الملفات النصية أو الثنائية بخطوات قليلة فقط.

python-logo-over-blurred-python-code-background-with-the-word-python-written-in-yellow-underneath كيفية استخدام دالة open في Python لقراءة وكتابة الملفات

تعلم استخدام هذه الدالة بشكل صحيح يوفر الكثير من الوقت ويجنب الأخطاء الشائعة عند التعامل مع الملفات. في هذا الدليل ستتعرف على كيفية استخدام open() لفتح الملفات بطرق مختلفة، وكيفية تحديد الوضع المناسب للقراءة أو الكتابة، إلى جانب أمثلة عملية تساعدك على فهمها وتطبيقها بسهولة.

ينبغي أن تكون دالة open في بايثون هي خيارك الأول عند قراءة محتويات ملف. أعطِه اسم ملف، وستحصل على كائن متعدد الاستخدامات، يتيح لك قراءة البيانات وكتابتها، سواءً بصيغة نص عادي أو ثنائي.

توضح هذه الأمثلة مدى مرونة هذه الدالة، مع دعمها لأوضاع مختلفة، والتخزين المؤقت، والترميز، وغيرها.

فتح ملف وقراءة محتوياته

لدالة open() توقيع معقد نوعًا ما، ولكن في أبسط الحالات، يمكنك استخدامها لفتح ملف نصي كما يلي:

f = open(filename)

يفتح بايثون هذا الملف افتراضيًا في وضع القراءة، مما يعني أنه يمكنك القراءة منه فقط. هذا مثالي لملفات التكوين، وملفات البيانات الثابتة، و… كما أنه يجعل هذه الحالة الشائعة موجزة وسهلة التذكر.

تعيد الدالة open() كائن ملف يمكنك استخدامه لتنفيذ مهام مختلفة، بما في ذلك قراءة محتويات الملف كاملةً:

f = open("/usr/share/dict/words")
text = f.read()
print(text)

file-not-exist كيفية استخدام دالة open في Python لقراءة وكتابة الملفات

لاحظ أن هذا المقطع البسيط سوف يتسبب في قيام Python بإثارة استثناء إذا لم يكن الملف موجودًا:

الملف الوحيد المضمون هو النص البرمجي الذي تُشغّله، والذي يُتيحه بايثون في المتغير الخاص __file__. هذا يُسهّل كتابة نص برمجي يطبع شيفرته المصدرية الخاصة، والمعروفة أيضًا باسم quine:

f = open(__file__)
text = f.read()
print(text)

quine كيفية استخدام دالة open في Python لقراءة وكتابة الملفات

ملاحظة
إذا كنتَ مُتشددًا جدًا، فهذا ليس صحيحًا تمامًا، لأن قراءة ملف تُعتبر غشًا.

استخدام الكلمة المفتاحية with لإغلاق ملف تلقائيًا

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

f = open("/usr/share/dict/words")
text = f.read()
f.close()

نصيحة
احرص على إغلاق الملف بأسرع ما يمكن. على سبيل المثال، إذا فتحت ملفًا، وقرأت محتوياته، ثم عالجتها، فحاول إغلاقه فور قراءتها. لا داعي لإبقاء الملف مفتوحًا أثناء معالجة البيانات التي قرأتها في متغير.

اقرأ أيضا:  كيفية الحذف التلقائي للرسائل على Telegram

ولكن قد تحدث مشاكل: ماذا لو لم يعمل استدعاء close() بشكل صحيح؟ للتغلب على هذه المشكلة، استخدم الكلمة المفتاحية with. يؤدي هذا إلى إنشاء مدير سياق للكتلة التي يغلفها، مما يضمن تحرير موارد الملف:

with open("/usr/share/dict/words") as f:
    text = f.read()

نسخ ملف عن طريق القراءة والكتابة

توفر مكتبات بايثون المختلفة طرقًا لنسخ ملف، لذا فإن هذا المثال توضيحي بحت. يوضح استخدام الوسيطة الثانية لـ open، وهي mode. تُخبر هذه الوسيطة open بكيفية استخدام الملف. يمكنك استخدام أي تركيبة صحيحة من هذه الأحرف:

Character Meaning
r Read
w Write
x Create & write
a Append
b Binary
t Text
+ Update

الوضع الافتراضي هو rt (قراءة ملف نصي)، ولذلك عمل المثال الأول في هذه المقالة كما هو متوقع. لنسخ الملف الذي تقرأ منه، ستحتاج إلى فتح ملف ثانٍ باستخدام الوضع w للكتابة. ستحتاج أيضًا إلى استخدام الوضع b لكليهما لضمان مراعاة عمليات القراءة والكتابة للبيانات الثنائية.

source = "./image.jpg"
target = "./a-copy-of-image.jpg"

with open(source, "rb") as src, open(target, "wb") as tgt:
    buffer = src.read()
    tgt.write(buffer)

تعمل كتلة with على كلا الملفين، لذا ستغلقهما تلقائيًا بمجرد اكتمالها.

ملاحظة
بينما تمنحك دالة open في بايثون وصولاً منخفض المستوى إلى محتويات الملف، توفر وحدة os العديد من الدوال عالية المستوى التي تعمل على الملفات ونظام الملفات.

إنشاء ملف نصي جديد

يمكنك أيضًا استخدام وسيطة mode لإنشاء ملف جديد، ولكن مع حماية أي ملف يحمل الاسم نفسه قد يكون موجودًا بالفعل:

open(filename, "x")

إذا كان الملف الذي يحمل الاسم نفسه موجودًا بالفعل، فسيؤدي هذا الاستدعاء المفتوح إلى استثناء FileExistsError. يُعد هذا إجراءً وقائيًا جيدًا يغني عن الحاجة إلى التحقق صراحةً من وجود الملف:

# Warning: don't do this!

import os.path

filename = "example.txt"

if os.path.isfile(filename):
    print("Sorry, file already exists")
else:
    with open(filename, "w") as f:
        # ...

إلى جانب كتابة شيفرة برمجية أقل، هناك سبب أفضل لاستخدام وضع “x”: فهو يتجنب حالة التسابق. لننظر إلى المثال أعلاه، الذي يتضمن عبارة واحدة للتحقق من وجود الملف (إذا كان os.path.isfile(filename))، متبوعة بعبارة أخرى لفتحه للكتابة (باستخدام open(filename, “w”) كـ f). إذا قامت عملية أخرى بإجراء ما على هذا الملف بين هاتين العبارتين، فقد تحدث كارثة.

اقرأ أيضا:  إصلاح عدم عمل إشعارات Snapchat

فتح ملف في وضع الإنشاء يمكن أن يجنب الكارثة، لأن عبارة واحدة مسؤولة عن التحقق من الملف وفتحه. إما أن تفشل العملية، ويكون الملف الموجود محميًا، أو تنجح، ولا يمكن لأي عملية أخرى إنشاء ملف آخر بنفس الاسم في هذه الأثناء.

الكتابة إلى ملف سجل عن طريق الإضافة

افتراضيًا، سيتم اقتطاع الملف الذي تفتحه في وضع الكتابة أولاً، وبالتالي سيتم استبدال محتوياته. لإضافة ملف، يمكنك استخدام وضع الإضافة:

log = open("file.log", "a")

مرة أخرى، يُسهّل تسجيل الدخول في بايثون استخدام وحدة التسجيل، التي تُعالج العديد من التفاصيل المُربكة. على سبيل المثال، يُمكنك تسجيل الدخول إلى ملف باستخدام شيفرة مشابهة لما يلي:

def startup():
    print("Just a dummy")

def main():
    print("Doing the main thing")
    return 42

def log(msg):
    logfile.write(msg + "\n")

logfile = open("file.log", "w")

log("starting startup")
startup()
log("startup finished")

log("starting main")
ret = main()
log("main finished: " + str(ret))

logfile.close()

استخدم التخزين المؤقت للتحكم في حفظ الملفات

لتجنب إعادة فتح الملف نفسه وحفظه باستمرار، يستخدم مثال التسجيل متغيرًا عامًا ومُعرِّف ملف طويل الأمد. يبدو هذا مقبولًا في مثال بسيط، ولكن في الواقع، قد يعمل برنامجك بلا حدود، وقد ترغب في التحقق من ملف السجل هذا في أي وقت. إذا فعلت ذلك، فقد تُفاجأ:

while True:
    log(random.random())
    input("Press Enter to continue")

يُحاكي هذا الكود التسجيل الدوري لعملية طويلة الأمد. يمكنك التحكم في التسجيل بالضغط على مفتاح الإدخال (Enter) عند الرغبة في تسجيل سطر آخر. مع ذلك، عند تشغيله، ستلاحظ عيبًا كبيرًا: إذا ضغطت على مفتاح الإدخال (Enter) عدة مرات وتحققت من ملف السجل، فستجد أنه لا يُكتب فيه أي شيء!

نصيحة
يمكن أن يساعدك أمر tail – وتحديدًا tail -f – في تتبع التغييرات على ملف السجل فورًا.

إذا ضغطت على مفتاح الإدخال (Enter) مرات كافية، فسترى بعض النتائج لأن الناتج سيكون قد تجاوز حجم المخزن المؤقت الافتراضي في بايثون. على نظامي، يبلغ هذا الحجم 8192 بايت، وسيستغرق تراكمه وقتًا طويلاً.

لحسن الحظ، في مثل هذه الحالات، توجد وسيطة التخزين المؤقت (buffering argument)، التي تتيح لك تحديد سياسة التخزين المؤقت. في حالة ملف السجل، يُعد التخزين المؤقت للأسطر طريقة رائعة، والتي

جرب تشغيل المثال السابق مع تعديل بسيط:

logfile = open("file.log", "w", 1)

الوسيطة الثالثة، 1، تُحدد التخزين المؤقت للأسطر. عند تفعيلها، ستلاحظ تحديث ملف السجل في كل مرة تُشغّل فيها دالة log() لأنها تتضمن حرف سطر جديد عند الكتابة إلى الملف.

اقرأ أيضا:  كيفية تمكين Dolby Atmos على iPhone و iPad و Mac

تحديد ترميز لدعم UTF-8 بشكل صحيح

ترميز الأحرف موضوع مُعقّد، لكن انتشار UTF-8 اليوم يعني أنك نادرًا ما تحتاج للقلق بشأنه. مع ذلك، قد تستخدم بعض الأنظمة القديمة ترميزات أخرى، ولا أحد يعلم ما قد يحدث في المستقبل. أخطاء الترميز قد تُسبب مشاكل كبيرة.

يُعد UTF-16 بديلاً عن UTF-8، وهو أكثر كفاءة لأنواع مُعينة من النصوص. مُعظم النصوص المكتوبة باللغة الإنجليزية مُناسبة بشكل أفضل لـ UTF-8، لكن النصوص المكتوبة بلغات أخرى، أو مجموعات الرموز – مثل ملف مليء بالرموز التعبيرية – ستكون أصغر حجمًا إذا تم تخزينها بتنسيق UTF-16.

إذا حاولت فتح ملف UTF-16 باستخدام طريقة الفتح القياسية، فسترى الخطأ التالي:

تتوقع وظيفة open – مع بعض التحذيرات – ترميز UTF-8 افتراضيًا، لذا ستحتاج إلى تحديد الترميز لفتح ملف UTF-16:

f = open("../utf16-file.txt", encoding="utf-16")

باستخدام وسيطة مُسمّاة، يمكنك ترك وسيطات الوضع والتخزين المؤقت افتراضية. أو يمكنك تحديد قيم افتراضية (أو مخصصة) لها:

f = open("../utf16-file.txt", "r", -1, "utf-16")

حتى إذا كنت تفتح ملفًا بترميز UTF-8، يُنصح بالإعلان صراحةً عن الترميز باستخدام هذه الوسيطة. قد تستخدم بعض أنظمة التشغيل (مثل Windows) ترميزًا غير UTF-8، لذا يُنصح بعدم الاعتماد على الإعداد الافتراضي.

utf16-bad كيفية استخدام دالة open في Python لقراءة وكتابة الملفات

معالجة الملفات ذات التنسيق الخاطئ باستخدام مُعامل الأخطاء

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

القيمة الافتراضية هي “strict”، والتي تُثير استثناءً، ولكن يمكنك تجاهل هذه الأخطاء تمامًا باستخدام “ignore”:

f = open("../utf16-file.txt", errors='ignore')

الجانب السلبي هو أنك قد تتعامل الآن مع بيانات تالفة دون علمك. يعتمد مدى قدرتك على التعامل مع هذا الأمر على طبيعة بياناتك.

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

وأخيرًا، ستستبدل قيمة “عكس مائل” كل حرف مشوه بما يعادله كتسلسل إفلات مع شرطة مائلة عكسية في بايثون. قد يساعدك هذا في تصحيح السبب الأصلي للمشكلة، لذا قد يكون مفيدًا للاختبار أو كجزء من مجموعة أدوات التطوير.

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

زر الذهاب إلى الأعلى