کار با فایلها
برنامههای واقعی نیاز به ذخیره و خواندن داده دارند. در این فصل با کار با فایلهای متنی، CSV، JSON و pathlib مدرن آشنا میشویم.
برنامههای واقعی نیاز به ذخیره و خواندن داده دارند. در این فصل با کار با فایلهای متنی، CSV، JSON و pathlib مدرن آشنا میشویم.
تابع open()
# ساختار کلی
file = open("filename.txt", mode="r", encoding="utf-8")
# ... کار با فایل
file.close() # حتماً ببندید!
# روش بهتر: with statement
with open("filename.txt", "r", encoding="utf-8") as file:
content = file.read()
# فایل بهصورت خودکار بسته میشود
حالتهای (mode) باز کردن
| mode | توضیح |
|---|---|
"r" |
فقط خواندن (پیشفرض). فایل باید موجود باشد. |
"w" |
نوشتن. اگر فایل بود، محتوا پاک میشود. |
"a" |
اضافه کردن (append) به انتهای فایل. |
"x" |
ساخت فایل جدید. خطا اگر موجود باشد. |
"r+" |
خواندن و نوشتن همزمان. |
"rb" / "wb" |
دودویی (binary) – برای تصویر، PDF و… |
⚠️ مهم برای فارسی:
همیشه encoding="utf-8" را تعیین کنید تا متن فارسی درست خوانده/نوشته شود. در ویندوز پیشفرض cp1252 یا cp1256 است که فارسی را خراب میکند.
خواندن فایل
# خواندن کل فایل
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# خواندن خط به خط (حلقه)
with open("notes.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.rstrip()) # rstrip حذف n انتها
# خواندن یک خط
with open("notes.txt", "r", encoding="utf-8") as f:
first_line = f.readline()
# خواندن همه خطوط در لیست
with open("notes.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines) # ['خط اولn', 'خط دومn', ...]
# خواندن فقط N کاراکتر
with open("notes.txt", "r", encoding="utf-8") as f:
chunk = f.read(100) # 100 کاراکتر اول
نوشتن فایل
# نوشتن (با w محتوای قبلی پاک میشود!)
with open("output.txt", "w", encoding="utf-8") as f:
f.write("سلام دنیاn")
f.write("خط دومn")
f.write("خط سومn")
# نوشتن چند خط
lines = ["خط ۱n", "خط ۲n", "خط ۳n"]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
# اضافه کردن (بدون پاک کردن قبلی)
with open("log.txt", "a", encoding="utf-8") as f:
f.write(f"n[{datetime.now()}] رویداد جدید")
# نوشتن لیست با خط جدید
items = ["سیب", "موز", "پرتقال"]
with open("fruits.txt", "w", encoding="utf-8") as f:
f.write("n".join(items))
کار با CSV
CSV (Comma-Separated Values) فرمت پرکاربرد برای دادههای جدولی:
خواندن CSV
import csv
# خواندن ساده
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row) # ['ali', '25', 'Tehran']
# با هدر
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader) # خط اول
print("ستونها:", header)
for row in reader:
print(row)
# DictReader - دسترسی با اسم ستون (بهتر!)
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["age"])
نوشتن CSV
import csv
# نوشتن با writer
data = [
["نام", "سن", "شهر"],
["علی", 25, "کاشان"],
["زهرا", 30, "تهران"],
["محمد", 28, "اصفهان"],
]
with open("output.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerows(data)
# DictWriter - با کلید (بهتر!)
records = [
{"name": "علی", "age": 25, "city": "کاشان"},
{"name": "زهرا", "age": 30, "city": "تهران"},
]
with open("users.csv", "w", encoding="utf-8", newline="") as f:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(records)
💡 برای Excel فارسی:
اگر CSV را در Excel باز کنید و فارسی خراب باشد، با encoding=”utf-8-sig” بنویسید (BOM اضافه میکند):
with open("file.csv", "w", encoding="utf-8-sig", newline="") as f: ...
کار با JSON
JSON فرمت استاندارد تبادل داده در API و وب است:
import json
# تبدیل dict پایتون به رشته JSON
data = {
"name": "محمدعلی",
"age": 35,
"skills": ["Python", "Django"],
"is_active": True,
"balance": None
}
# dumps - تبدیل به رشته
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
# loads - تبدیل رشته به dict
parsed = json.loads(json_str)
print(parsed["name"])
# نوشتن در فایل
with open("user.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# خواندن از فایل
with open("user.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["skills"])
پارامترهای مهم json.dump
json.dump(data, f,
ensure_ascii=False, # ← مهم برای فارسی!
indent=2, # تورفتگی برای خوانایی
sort_keys=True, # مرتب کردن کلیدها
)
نگاشت نوع داده
| پایتون | JSON |
|---|---|
| dict | object {} |
| list, tuple | array [] |
| str | string |
| int, float | number |
| True / False | true / false |
| None | null |
pathlib – راه مدرن
pathlib (از Python 3.4) جایگزین مدرن و شیءگرای os.path است:
from pathlib import Path
# مسیر جاری
current = Path.cwd()
print(current)
# مسیر home
home = Path.home()
# ساخت مسیر (cross-platform!)
config = Path("data") / "config" / "settings.json"
print(config) # data/config/settings.json (لینوکس)
# dataconfigsettings.json (ویندوز)
# اطلاعات مسیر
p = Path("/home/ali/project/file.txt")
print(p.name) # file.txt
print(p.stem) # file (بدون پسوند)
print(p.suffix) # .txt
print(p.parent) # /home/ali/project
print(p.parts) # ('/', 'home', 'ali', 'project', 'file.txt')
# بررسی وجود
print(p.exists())
print(p.is_file())
print(p.is_dir())
# ساخت پوشه
Path("data/cache").mkdir(parents=True, exist_ok=True)
# لیست محتوای پوشه
for item in Path(".").iterdir():
print(item)
# جستجوی glob
for py_file in Path(".").glob("*.py"):
print(py_file)
# جستجوی recursive
for txt in Path(".").rglob("*.txt"):
print(txt)
# خواندن/نوشتن مستقیم!
content = Path("notes.txt").read_text(encoding="utf-8")
Path("output.txt").write_text("سلام", encoding="utf-8")
# حذف
Path("temp.txt").unlink() # فایل
Path("empty_dir").rmdir() # پوشه خالی
مثالهای واقعی
لاگ کردن رویدادها
from datetime import datetime
def log(message):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("app.log", "a", encoding="utf-8") as f:
f.write(f"[{timestamp}] {message}n")
log("شروع برنامه")
log("کاربر ali وارد شد")
log("درخواست API ارسال شد")
شمارش کلمات در فایل
from collections import Counter
from pathlib import Path
text = Path("article.txt").read_text(encoding="utf-8")
words = text.split()
counts = Counter(words)
print("۱۰ کلمه پرتکرار:")
for word, count in counts.most_common(10):
print(f"{word}: {count}")
پشتیبانگیری دیتا
import json
from datetime import datetime
from pathlib import Path
def backup_data(data, base_name="backup"):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{base_name}_{timestamp}.json"
Path("backups").mkdir(exist_ok=True)
backup_path = Path("backups") / filename
with open(backup_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"پشتیبان ذخیره شد: {backup_path}")
users = [{"name": "علی", "age": 25}]
backup_data(users, "users")
تبدیل CSV به JSON
import csv
import json
def csv_to_json(csv_path, json_path):
with open(csv_path, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
data = list(reader)
with open(json_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"تبدیل شد: {csv_path} → {json_path}")
csv_to_json("users.csv", "users.json")
تمرین فصل
🏋️ تمرین ۱: فایلی بسازید با ۱۰ خط متن. سپس خط به خط بخوانید و فقط خطوط زوج را در فایل دوم بنویسید.
🏋️ تمرین ۲: دفترچه تلفن: یک JSON با مخاطبین بسازید و با عملیات افزودن، حذف و جستجو کار کنید.
🏋️ تمرین ۳: با pathlib، تمام فایلهای
.py در یک پوشه را بیابید و طول هر فایل (تعداد خطوط) را در یک CSV ذخیره کنید.
🏋️ تمرین ۴: سیستم لاگ سادهای بنویسید که هر رویداد را با timestamp و سطح (INFO، WARNING، ERROR) ذخیره کند.
جمعبندی
- تابع
open()با حالتهای مختلف - الزام
encoding="utf-8"برای فارسی - استفاده از
withبرای بستن خودکار - خواندن:
read،readline،readlines، حلقه - نوشتن:
write،writelines - CSV با
csv.DictReaderوcsv.DictWriter - JSON با
json.dumpوjson.load+ensure_ascii=False pathlib.Path– روش مدرن کار با مسیرها