فتح ملف باستخدام `with`
تختفي المتغيرات عند انتهاء البرنامج، أما الملفات فلا. تعطيك open(path, mode) كائن ملف، ويحدد mode ما تريد: "r" للقراءة (الافتراضي)، و"w" للكتابة، و"a" للإضافة. افتح الملفات دائمًا بكتلة with: with open(path) as file:. عند انتهاء الكتلة تغلق بايثون الملف عنك حتى لو حدث خطأ بداخلها، فلا تضيع البيانات ولا تبقى مكتوبة جزئيًا. مرّر encoding="utf-8" ليُقرأ النص ويُكتب بالطريقة نفسها على كل حاسوب.
# Write a file, then read it back
with open("fills.txt", "w", encoding="utf-8") as file:
file.write("AAPL,184.25,200\n")
file.write("MSFT,410.20,50\n")
with open("fills.txt", encoding="utf-8") as file:
text = file.read()
print(repr(text)) # 'AAPL,184.25,200\nMSFT,410.20,50\n'القراءة سطرًا بسطر
تُرجع file.read() الملف كله في نص واحد. والأشيع أن تمرّ على كائن الملف نفسه، فيعطيك سطرًا واحدًا في كل مرة ويصلح لملفات أكبر من الذاكرة: for line in file:. وكل سطر ما زال ينتهي بـ\n، فنظّفه بـline.strip(). يصير السطر الفارغ بعد التنظيف النص الفارغ "" وهو يعدّ خاطئًا، فيتخطاه if text:. وتعطي file.readlines() وtext.splitlines() قوائم أسطر حين تريدها كلها دفعة واحدة.
# Read line by line, skipping blank lines
with open("fills.txt", "a", encoding="utf-8") as file:
file.write("\n") # a blank line
total = 0.0
with open("fills.txt", encoding="utf-8") as file:
for line in file:
text = line.strip()
if not text:
continue
symbol, price, quantity = text.split(",")
total += float(price) * int(quantity)
print(round(total, 2)) # 57360.0الكتابة والإضافة
تكتب file.write(text) النص الذي تعطيه بالضبط وتُرجع عدد الأحرف. وهي لا تضيف فاصل سطر، فأنهِ كل سطر بـ"\n" بنفسك. يقوم الوضع "w" أولًا بـإفراغ الملف (وينشئه إن لم يكن موجودًا)، فيؤدي فتح ملف موجود بـ"w" إلى رمي محتواه القديم. أما الوضع "a" فيُبقي الموجود ويضيف في النهاية. ولا يُكتب إلا النصوص: حوّل الأرقام أولًا، مثلًا بنص مُنسَّق مثل f"{price:.2f}".
# "w" starts over, "a" adds to the end
with open("log.txt", "w", encoding="utf-8") as file:
file.write("start\n")
with open("log.txt", "a", encoding="utf-8") as file:
file.write("order 1 filled\n")
file.write(f"pnl {12.5:+.2f}\n")
with open("log.txt", encoding="utf-8") as file:
print(file.read().splitlines()) # ['start', 'order 1 filled', 'pnl +12.50']
with open("log.txt", "w", encoding="utf-8") as file:
pass # opening with "w" emptied it
with open("log.txt", encoding="utf-8") as file:
print(repr(file.read())) # ''المسارات والملفات المفقودة
يُبحث عن المسار النسبي مثل "fills.txt" في المجلد الحالي للبرنامج؛ استخدم os.path.join(folder, name) لبناء المسارات دون قلق بشأن الفواصل. فتح ملف غير موجود للقراءة يرفع FileNotFoundError، ويمكنك التقاطه بـtry/except حين يكون غيابه حالة متوقعة. وللملفات الصغيرة، تقوم pathlib.Path(path).read_text() و.write_text(text) بالفتح والقراءة أو الكتابة والإغلاق في استدعاء واحد.
import os
from pathlib import Path
# A missing file is an exception you can handle
def count_lines(path):
try:
with open(path, encoding="utf-8") as file:
return len(file.read().splitlines())
except FileNotFoundError:
return 0
print(count_lines("fills.txt")) # 3
print(count_lines("nope.txt")) # 0
# pathlib does open + read + close in one call
path = Path(os.path.join(".", "fills.txt"))
print(path.read_text(encoding="utf-8").splitlines()[0]) # AAPL,184.25,200"w" على المسار الخطأ يتلف البيانات دون تراجع. اختر تنسيقًا بسيطًا (سجل لكل سطر وحقول مفصولة بفواصل) واكتب القارئ والكاتب معًا ليتفقا عليه. ستتعرف قريبًا على تنسيق CSV الذي يضفي طابعًا رسميًا على هذه الفكرة بالذات.with open(path, mode, encoding="utf-8") as file:تفتح الملف وتغلقه دائمًا.for line in file:تقرأ سطرًا في كل مرة؛ وline.strip()تزيل فاصل السطر."w"تفرغ الملف، و"a"تضيف؛ وwriteلا تضيف فاصل سطر.
التالي: ملفات CSV، الطريقة القياسية لتخزين جداول الأسعار والصفقات.
المختبر: ما الذي يُقيَّم
- حمّل قائمة متابعة من ملف باستخدام
read_symbols25 نقطة - حوّل ملف تنفيذات إلى صفوف باستخدام
parse_trades25 نقطة - احفظ تقرير الأرباح والخسائر باستخدام
write_report25 نقطة - أضف إلى سجل دون فقدانه باستخدام
append_lines25 نقطة