7.2. قراءة الملفات والكتابة
افتح () إرجاع كائن ملف ، ويتم استخدامه بشكل شائع مع وسيطتين: فتح (اسم الملف ، الوضع).
>>> f = open('workfile', 'w')
الوسيطة الأولى هي سلسلة تحتوي على اسم الملف. الوسيطة الثانية هي سلسلة أخرى تحتوي على بضعة أحرف تصف الطريقة التي سيتم بها استخدام الملف. يمكن أن يكون الوضع “R” عندما يتم قراءة الملف فقط ، “W” للكتابة فقط (سيتم محو ملف موجود بنفس الاسم) ، و “A” يفتح الملف لإلحاقه ؛ تتم إضافة أي بيانات مكتوبة إلى الملف تلقائيًا إلى النهاية. “R+” يفتح الملف لكل من القراءة والكتابة. وسيطة الوضع اختيارية ؛ سيتم افتراض “R” إذا تم حذفه.
عادة ، يتم فتح الملفات في وضع النص ، وهذا يعني أنك تقرأ وتتمكن من كتابة السلاسل من الملف وإلى الملف ، والتي يتم ترميزها في ترميز معين. إذا لم يتم تحديد الترميز ، فإن الافتراضي يعتمد على النظام الأساسي (انظر Open ()). يفتح “B” المُلحق بالوضع الملف في الوضع الثنائي: الآن تتم قراءة البيانات وكتابتها في شكل كائنات بايت. يجب استخدام هذا الوضع لجميع الملفات التي لا تحتوي على نص.
في وضع النص ، يكون الافتراضي عند القراءة هو تحويل نهايات الأسطر الخاصة بالنظام الأساسي (
\ n على unix ، \ r \ n على windows) إلى \ n فقط. عند الكتابة في وضع النص ، يكون الافتراضي هو تحويل حوادث العودة إلى نهايات الخط الخاصة بالمنصة. يعد هذا التعديل من وراء الكواليس على ملفات الملفات جيدًا بالنسبة للملفات النصية ، ولكنه سوف يفسد البيانات الثنائية مثل تلك الموجودة في ملفات JPEG أو EXE. كن حذرًا جدًا في استخدام الوضع الثنائي عند قراءة هذه الملفات وكتابةها.
من الممارسات الجيدة استخدام الكلمة الرئيسية عند التعامل مع كائنات الملف. الميزة هي أن الملف مغلق بشكل صحيح بعد انتهاء جناحه ، حتى إذا تم إثارة استثناء في مرحلة ما. الاستخدام مع هو أيضا أقصر بكثير من كتابة كتل تجربية مكافئة:
>>> with open('workfile') as f:
... read_data = f.read()
>>> # We can check that the file has been automatically closed.
>>> f.closed
True
إذا كنت لا تستخدم الكلمة الرئيسية مع الكلمة الرئيسية ، فيجب عليك الاتصال بـ F.Close () لإغلاق الملف وتحرير أي موارد النظام التي تستخدمها على الفور.
تحذير استدعاء f.write () دون استخدام الكلمة الرئيسية أو الاتصال f.close () قد يؤدي إلى وسيطات f.write () لا يتم كتابة تماما على القرص ، حتى إذا خرج البرنامج بنجاح.
بعد إغلاق كائن ملف ، إما عن طريق بيان أو عن طريق الاتصال بـ F.Close () ، سيفشل محاولات استخدام كائن الملف تلقائيًا.
>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
7.2.1. طرق كائنات الملف #
سوف تفترض بقية الأمثلة في هذا القسم أنه تم إنشاء كائن ملف يسمى F بالفعل.
لقراءة محتويات الملف ، اتصل بـ F.Read (الحجم) ، الذي يقرأ بعض كمية البيانات ويعيدها كسلسلة (في وضع النص) أو كائن Bytes (في الوضع الثنائي). الحجم هو وسيطة رقمية اختيارية. عندما يتم حذف الحجم أو سلبي ، سيتم قراءة محتويات الملف بالكامل وإعادتها ؛ إنها مشكلتك إذا كان الملف كبيرًا مثل ذاكرة جهازك. خلاف ذلك ، يتم قراءة وإعادت في معظم أحرف الحجم (في وضع النص) أو بايت الحجم (في الوضع الثنائي). إذا تم الوصول إلى نهاية الملف ، فسيقوم F.Read () بإرجاع سلسلة فارغة (”).
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
F.ReadLine () يقرأ سطر واحد من الملف ؛ يتم ترك حرف خط جديد (\ n) في نهاية السلسلة ، ويتم حذفه فقط على السطر الأخير من الملف إذا لم ينتهي الملف في خط جديد. هذا يجعل قيمة الإرجاع لا لبس فيها ؛ إذا قام F.ReadLine () بإرجاع سلسلة فارغة ، فقد تم الوصول إلى نهاية الملف ، بينما يتم تمثيل سطر فارغ بـ ‘\ n’ ، وهي سلسلة تحتوي فقط على سطر جديد واحد.
>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''
لقراءة الخطوط من ملف ، يمكنك حلقة كائن الملف. هذا فعال للذاكرة وسريع ويؤدي إلى رمز بسيط:
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
إذا كنت ترغب في قراءة جميع خطوط ملف في قائمة ، يمكنك أيضًا استخدام القائمة (F) أو F.Readlines ().
يكتب F.write (سلسلة) محتويات السلسلة إلى الملف ، وإرجاع عدد الأحرف المكتوبة.
>>> f.write('This is a test\n')
15
يجب تحويل أنواع أخرى من الكائنات – إما إلى سلسلة (في وضع النص) أو كائن بايت (في الوضع الثنائي) – قبل كتابتها:
>>> value = ('the answer', 42)
>>> s = str(value) # convert the tuple to string
>>> f.write(s)
18
يقوم F.Tell () بإرجاع عدد صحيح يعطي الموضع الحالي لكائن الملف في الملف ممثلًا على أنه عدد من البايتات من بداية الملف عندما يكون في الوضع الثنائي ورقمًا غير شفاف عند وضع النص.
لتغيير موضع كائن الملف ، استخدم f.eek (الإزاحة ، من أين). يتم حساب الموضع من إضافة الإزاحة إلى نقطة مرجعية ؛ يتم تحديد النقطة المرجعية من خلال الوسيطة. من حيث القيمة 0 من بداية الملف ، يستخدم 1 موضع الملف الحالي ، ويستخدم 2 نهاية الملف كنقطة مرجعية. من أين يمكن حذفه وإعداد الافتراضات إلى 0 ، باستخدام بداية الملف كنقطة مرجعية.
>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5) # Go to the 6th byte in the file
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # Go to the 3rd byte before the end
13
>>> f.read(1)
b'd'
في الملفات النصية (تلك التي تم فتحها بدون B في سلسلة الوضع) ، يسعى فقط إلى بداية الملف (الاستثناء الذي يبحث عن نهاية الملف ذاته مع Seek (0 ، 2)) وقيم الإزاحة الصالحة الوحيدة هي تلك التي يتم إرجاعها من F.Tell () أو صفر. أي قيمة إزاحة أخرى تنتج سلوكًا غير محدد.
تحتوي كائنات الملفات على بعض الطرق الإضافية ، مثل ISATTY () و TRUNCATE () والتي يتم استخدامها بشكل متكرر ؛ راجع مرجع المكتبة للحصول على دليل كامل لكائنات الملف.
7.2.2. حفظ البيانات المنظمة مع JSON #
يمكن بسهولة كتابة الأوتار والقراءة من ملف. تستغرق الأرقام المزيد من الجهد ، نظرًا لأن طريقة القراءة () تُرجع فقط سلاسل ، والتي يجب نقلها إلى وظيفة مثل
int () ، التي تأخذ سلسلة مثل “123” وإرجاع قيمتها الرقمية 123. عندما تريد حفظ أنواع البيانات الأكثر تعقيدًا مثل القوائم المتداخلة والقواميس ، يصبح التحليل والتسلسل باليد معقدًا.
بدلاً من وجود المستخدمين باستمرار في كتابة وتصحيح رمز لحفظ أنواع البيانات المعقدة للملفات ، يتيح لك Python استخدام تنسيق تبادل البيانات الشهير المسمى JSON (تدوين كائن JavaScript). يمكن للوحدة القياسية التي تسمى JSON أخذ التسلسلات الهرمية لبيانات بيثون ، وتحويلها إلى تمثيلات سلسلة ؛ وتسمى هذه العملية التسلسل. يُطلق على إعادة بناء البيانات من تمثيل السلسلة. بين التسلسل والتسلسل ، قد يتم تخزين السلسلة التي تمثل الكائن في ملف أو بيانات ، أو إرسالها عبر اتصال شبكة ببعض الجهاز البعيد.
لاحظ أن تنسيق JSON يستخدم بشكل شائع من قبل التطبيقات الحديثة للسماح بتبادل البيانات. العديد من المبرمجين على دراية به بالفعل ، مما يجعلها خيارًا جيدًا للتشغيل البيني.
إذا كان لديك كائن X ، فيمكنك عرض تمثيل سلسلة JSON مع سطر رمز بسيط:
>>> import json
>>> json.dumps([1, 'simple', 'list'])
'[1, "simple", "list"]'
متغير آخر من دالة Dumps () ، يسمى Dump () ، ببساطة يسلسل الكائن إلى ملف نصي. لذلك إذا كان F هو كائن ملف نصي مفتوح للكتابة ، فيمكننا القيام بذلك:
json.dump(x, f)
لفك تشفير الكائن مرة أخرى ، إذا كان F هو كائن ملف نصي تم فتحه للقراءة:
x = json.load(f)
يمكن لهذه التقنية التسلسلية البسيطة التعامل مع القوائم والقواميس ، ولكن تخصيص حالات الطبقة التعسفية في JSON تتطلب القليل من الجهد الإضافي. تحتوي المرجع لوحدة JSON على شرح لهذا.
انظر أيضًا Pickle – وحدة المخلل
على عكس JSON، فإن المخلل هو بروتوكول يسمح بتسلسل كائنات الثعبان المعقدة بشكل تعسفي. على هذا النحو ، فهي خاصة بـ Python ولا يمكن استخدامها للتواصل مع التطبيقات المكتوبة بلغات أخرى. كما أنه غير آمن افتراضيًا: يمكن لبيانات المخلل القادمة من مصدر غير موثوق تنفيذ رمز تعسفي ، إذا تم تصميم البيانات من قبل مهاجم ماهر.