الدالة open()‎ في بايثون

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

تفتح الدّالة open()‎ ملفّا وتعيد كائن ملفّ (file object) مرتبط به.

إن لم يُمكِن فتح الملفّ، فسيُطلَق الاستثناء OSError‎.

البنية العامة

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

المعاملات

file

كائن مُشابه للمسارات (path-like object) يُمثّل مسار الملفّ (سواء أكان مُطلقا أو نسبيًّا) المرغوب فتحه.

يُمكن كذلك أن يكون واصف ملفّ عدديّ (integer file descriptor) للملفّ لتغطيّته (wrap). إن مُرّر واصف ملفّات، فسيُغلَق عندما يُغلَق كائن I/O المُعاد، إلّا في حالة كانت قيمة المُعامل closefd تساوي False.

mode

مُعامل اختياريّ.

سلسلة نصيّة تُحدّد الوضع الذي سيُفتح فيه الملفّ. القيمة الافتراضيّة هي ‎'‎r‎'‎ والتي تعني أنّ الملفّ سيُفتح في وضع القراءة. ومن القيم الشّائعة:

  • ‎'w‎'‎ لفتح الملفّ في وضع الكتابة (مع حذف الملفّ إن كان موجودًا مُسبقًا).
  • ‎'x‎'‎ لإنشاء الملفّات حصرًا.
  • ‎'‎a‎'‎ لإضافة المحتويات إلى نهاية الملفّ دون حذفه إن كان موجودًا مُسبقًا (والتي تعني في بعض أنظمة يونكس أنّ الكتابة ستكون دائمًا على نهاية الملفّ بغضّ النّظر عن موقع المؤشر الحاليّ).

والأوضاع المُتاحة هي كالتّالي:

المحرف المعنى
‎'r‎'‎ فتح الملفّ للقراءة (الوضع الافتراضيّ)
‎'w‎'‎ فتح الملفّ للكتابة، مع حذف محتويات الملفّ إن كان موجودًا
‎'x‎'‎ فتح الملفّ للإنشاء حصرًا، أي أنّ فتح الملفّ سيفشل إن كان موجودًا مُسبقًا
‎'a‎'‎ فتح الملفّ للكتابة مع الكتابة إلى نهاية الملفّ إن كان موجودًا مُسبقًا
‎'b‎'‎ الوضع الثّنائي (binary mode)
‎'t‎'‎ وضع النّصوص (الوضع الافتراضيّ)
‎'+‎'‎ فتح ملفّ على القرص لتعديله (القراءة والكتابة)
‎'U'‎ وضع الأسطر الجديدة العامّة (universal newlines) وهو وضع مُهمل لا يجب استخدامه.

الوضع الافتراضي هو ‎'r‎'‎ (لفتح الملفّ لقراءة النّصوص، وهو نفسه الوضع ‎'rt‎'‎). للقراءة والكتابة للملفّ بشكل ثُنائيّ، يُمكن استخدام الوضع ‎'w+b‎'‎ لفتح ملفّ وحذف محتوياته إلى 0 بايت. والوضع ‎'r+b‎'‎ يفتح الملفّ دون حذف محتوياته.

وكما ذُكر في تمهيد الوحدة io، لغة بايثون تُفرّق بين كائنات I/O الثّنائية وكائنات I/O النّصيّة. تُعيد الملفّات المفتوحة في الوضع الثّنائي (أي عندما يشمل الوضع المحرف ‎'b‎'‎) المحتويات على شكل كائنات بايتات دون فكّ ترميزها (decoding). وأمّا في الوضع النّصيّ (وهو الوضع الافتراضيّ، أو عندما يشمل الوضع المحرف ‎'t‎'‎)، فتُعاد المحتويات على شكل سلاسل نصيّة، وذلك عبر فكّ ترميز البايتات أولًا باستخدام ترميز يعتمد على نظام التّشغيل أو باستخدام التّرميز المُمرّر للمُعامل encoding.

مُلاحظة: لا تعتمد بايثون على نظام التّشغيل لمعالجة الملفّات النّصيّة، إذ تُعالَج باستخدام لغة بايثون نفسها ما يجعلها مستقلّة عن المنصّة التي تعمل فيها.

buffering

مُعامل اختياريّ.

عدد صحيح يُستعمل لضبط سياسة التّخزين الانتقاليّ (buffering). مرّر القيمةَ 0 لتعطيل التخزين الانتقاليّ (مسموح به في الوضع الثّنائيّ فقط)، أو القيمةَ 1 لاختيار تخزين الأسطر (line buffering) والذي يكون مسموحًا به في الوضع النّصيّ فقط، أو مرّر عددًا صحيحًا أكبر من واحد لتحديد حجم البايتات لمخزن قطع ثابت الحجم (fixed-size chunk buffer).

عندما لا تُمرّر أيّة مُعاملات إلى المُعامل buffering فستعمل سياسة التّخزين الانتقاليّ كما يلي:

  • تُخزّن الملفّات الثّنائيّة في قطع ثابتة الحجم؛ يُحدَّدُ حجم المخزن عبر محاولة الحصول على حجم القطع (block size) الخاصّ بالجهاز، أو تُستعمل القيمة ‎io‎.‎DEFAULT_BUFFER_SIZE‎ إن فشلت المُحاولة. يكون حجم المخزن في العديد من الأنظمة عادةً إمّا 4096 أو 8192 بايت.
  • تستعمل الملفّات النّصيّة التّفاعليّة (التي يُعيد فيها استدعاء التّابع ‎‎isatty‎(‎)‎ القيمة True) تخزين الأسطر. أمّا الملفّات النّصيّة الأخرى فتستعمل سياسة الملفّات الثّنائية الموضّحة أعلاه.

encoding

مُعامل اختياريّ.

اسم التّرميز الذي سيُستعمل لفكّ ترميز وترميز الملفّ. يجب استخدامه فقط في وضع الملفّات النّصيّة. في وضع الملفّات النّصيّة، إن لم تُمرّر قيمة للمُعامل encoding فالتّرميز المستخدم سيعتمد على نظام التّشغيل، وسيُستعمل الاستدعاء ‎locale‎.‎getpreferredencoding‎(‎False‎)‎ للحصول على التّرميز المحليّ. (ولقراءة وكتابة البايتات الخام، استعمل الوضع الثّنائي واترك تحديد قيمة للمُعامل encoding.) لكن يُمكن استخدام أي ترميز نصوص تدعمه بايثون. انظر الوحدة codecs للحصول على قائمة بالتّرميزات المدعومة.

errors

مُعامل اختياريّ.

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

  • ‎'‎strict‎'‎ لإطلاق استثناء ValueError‎ إن حدث خطأ في التّرميز. والقيمة الافتراضيّة للمُعامل (أي القيمة None‎) لها نفس التأثير.
  • ‎'‎ignore‎'‎ لتجاهل الأخطاء. لكن انتبه إلى أنّ تجاهل أخطاء التّرميز قد يتسبّب في فقدان البيانات.
  • ‎'‎replace‎'‎ لإبدال البيانات المشوّهة (التي حدثت عندها مشاكل في التّرميز) بعلامة مثل ‎'‎?‎'‎‎.
  • ‎'‎surrogateescape‎'‎ سيُمثّل أية بايتات غير صالحة لتكون على شكل نقاط شيفرة (code points) في مساحة الاستخدام الخاصّة ليونيكود (Unicode Private Use Area) ضمن المجال U‎+‎DC80‎ إلى ‎U‎+‎DCFF‎. ستُرجع بعد ذلك نقاط الشّيفرة الخاصّة هذه إلى نفس البايتات عندما يُستعمل مُعالج الأخطاء ‎surrogateescape‎ لكتابة البيانات. وهذا مُفيد لمُعالجة الملفّات مجهولة التّرميز.
  • ‎'‎xmlcharrefreplace‎'‎مدعوم فقط عند الكتابة إلى ملفّ. ويقوم بإبدال المحارف غير المدعومة من طرف التّرميز إلى مرجع المحرف في مراجع XML (على شاكلة ‎‎‎&‎#‎nnn‎;‎‎).
  • ‎'‎backslashreplace‎'‎ يُبدِل البيانات المُشوّهة بسلاسل التّهريب المسبوقة بالمحرف \‎ في بايثون.
  • ‎'‎namereplace‎'‎ مدعوم عند الكتابة فقط. يُبدل المحارف غير المدعومة بسلاسل التّهريب ‎‎\‎N‎{‎.‎.‎.‎}‎‎.

newline

مُعامل اختياريّ.

يتحكّم بكيفيّة عمل وضع الأسطر الجديدة العامّ (universal newlines mode) في الوضع النّصيّ. يُمكن للقيم أن تكون None، أو ، أو ‎'‎\‎n‎'‎، أو ‎'‎\‎r‎'‎، أو ‎'‎\‎r‎\‎n‎‎'‎‎. وتعمل كما يلي:

  • عند قراءة المُدخلات من التّيار (stream)، يكون وضع الأسطر الجديدة العامّ مُفعّلًا إن كانت قيمة المعامل newline تُساوي None. يُمكن للأسطر في المُدخل أن تنتهي بالمقطع ‎'‎\‎n‎'‎، أو ‎'‎\‎r‎'‎، أو ‎'‎\‎r‎\‎n‎'‎ وستُترجم إلى ‎'‎\‎n‎'‎ قبل إعادتها إلى المُستدعي. وإن كانت قيمة المعامل newline تُساوي ‎'‎'‎ فإنّ وضع الأسطر الجديدة العامّ يكون مُفعّلًا، لكنّ نهايات الأسطر تُعاد إلى المُستدعِي دون ترجمتها. وإن كانت قيمة المعامل newline تُساوي أيًّا من القيم الأخرى المسموح بها، فستنتهي الأسطر بالقيمة المُعطاة فقط، وستُعاد نهايات الأسطر إلى المُستدعِي دون ترجمتها.
  • عند الكتابة إلى الملفّ، إن كانت قيمة المعامل newline تُساوي None، فستُترجم أيّة محارف ‎'‎\‎n‎'‎ إلى فاصل الأسطر الافتراضي لنظام التّشغيل، والذي يُمكن الوصول إليه عبر الخاصيّة ‎os‎.‎linesep‎. وإن كانت قيمة المعامل newline تُساوي ‎'‎'‎ أو ‎'‎\‎n‎'‎ فلن تُترجم نهايات الأسطر. وإن كانت قيمة المعامل newline تُساوي أيًّا من القيم الأخرى المسموح بها، فستُترجم أيّة محارف ‎'‎\‎n‎'‎ إلى القيمة المُعطاة.

closefd

مُعامل اختياريّ.

إن كانت قيمته تُساوي القيمة False وإن أعطِيَ واصف ملفّ (file descriptor) عوضًا عن اسم ملفّ للمُعامل file، فسيبقى واصف الملفّ مفتوحًا عندما يُغلق الملفّ. إن أُعطيَ اسم ملفّ للمُعامل file فيجب على قيمة المُعامل closefd أن تُساوي True (وهي القيمة الافتراضيّة)، وإلّا سيُطلق استثناء ValueError.

opener

مُعامل اختياريّ.

يُستعمل هذا المُعامل لاستعمال فاتح ملفّات خاصّ عبر تمريره (على شكل كائنٍ قابل للاستدعاء) إلى المُعامل opener. ويُستخرج واصف الملفّ الضّمني لكائن الملفّ عبر استدعاء الكائن المُمرّر إلى المُعامل opener بالمُعاملات المُعطاة. ويجب على الكائن المُعطى أن يُعيد واصف ملفّ مفتوحًا (تمرير الدّالة ‎os‎.‎open كفاتح ملفّات له تأثير مُشابه لتمرير القيمة None الافتراضيّة). لاحظ أنّ الملفّ المُنشأ حديثًا غير قابل للوراثة (non‎-‎‎inheritable).

القيمة المعادة

كائن ملفّ يعتمد نوعه على الوضع الذي فُتح فيه الملفّ:

  • إن استُخدمت الدّالة open()‎ لفتح ملفّ في الوضع النّصيّ (إمّا ‎'‎w‎'‎ أو ‎'‎r‎'‎ أو ‎'‎wt‎'‎ أو ‎'‎rt‎'‎)، فستُعيد صنفًا فرعيًّا من الصّنف ‎io‎.‎TextIOBase‎ (الصّنف ‎io‎.‎TextIOWrapper‎ على وجه التّحديد).
  • إن استُخدمت لفتح ملفّ في الوضع الثّنائي (binary mode) مع التّخزين الانتقاليّ، فالصّنف المُعاد صنفٌ فرعيّ من الصّنف ‎io‎.‎BufferedIOBase‎. والصّنف ذاته يختلف، ففي وضع القراءة الثّنائيّ، سيُعاد ‎io‎.‎BufferedReader‎؛ وفي وضع الكتابة (والكتابة إلى آخر الملفّ) الثّنائيّ، سيُعاد ‎io‎.‎BufferedWriter‎، أمّا في وضع القراءة والكتابة، فيُعاد ‎io‎.‎BufferedRandom‎ وإن عُطّل التّخزين الانتقاليّ، فسيُعاد التّيار الخام، والذي يكون صنفًا فرعيًّا من ‎io‎.‎RawIOBase‎ أو ‎io‎.‎FileIO‎.

أمثلة

المثال التّالي يوضّح كيفيّة عمل هذه الدّالة لفتح ملفّ باسم name.txt وكتابة القيمة Ali إليه:

>>> with open('name.txt', 'w') as f:
...     f.write('Ali')
...

المثال التّالي يستعمل المُعامل dir_fd الخاصّ بالدّالة ‎os‎.‎open لفتح ملفّ نسبةً إلى مُجلّد مُعطى:

>>> import os
>>> dir_fd = os.open('somedir', os.O_RDONLY)
>>> def opener(path, flags):
...     return os.open(path, flags, dir_fd=dir_fd)
...
>>> with open('spamspam.txt', 'w', opener=opener) as f:
...     print('somedir/spamspam.txt', file=f) # تطبع مسار الملفّ الذي سيُكتب إليه السّطر
...
>>> os.close(dir_fd)  # أغلق واصف الملفّ

انظر أيضًا

مصادر