Python CLI จัดการไฟล์โปรเจกต์ให้เป๊ะ ด้วย Context Manager พร้อม Resilience

สวัสดีครับเพื่อนๆ โปรแกรมเมอร์ทุกคน

วันนี้ผมอยากชวนมาคุยเรื่องการจัดการไฟล์ในโปรเจกต์เรานะครับ บางทีเราเขียนโค้ดต้องไปยุ่งกับไฟล์เยอะแยะเลย ทั้งไฟล์ config ไฟล์ data หรือไฟล์ logs ต่างๆ แล้วถ้าจัดการไม่ดี โค้ดพัง ไฟล์เสียหาย ข้อมูลหาย โดนลูกค้าด่ามาที หลังหักเลยนะครับ ผมเจอมาบ่อยเลยแบบนี้

ทีนี้เราจะทำยังไงให้การจัดการไฟล์พวกนี้มัน Resilience หรือทนทานต่อความผิดพลาด แล้วก็ Optimize workflow การทำงานของเราด้วย ผมแนะนำให้ใช้ Context Manager ใน Python นี่แหละครับ มันช่วยเราได้เยอะมากเลย

Context Manager: เปิด-ปิดไฟล์อย่างปลอดภัย

ปกติเวลาเราเปิดไฟล์ เขียนเสร็จ เราก็ต้อง close() ใช่มั้ยครับ แต่ถ้าเกิด error ขึ้นมาก่อน close() ไฟล์เราก็ค้างอยู่แบบนั้นแหละครับ ทำให้เกิดปัญหาตามมาได้เยอะเลย

นี่ครับ ตัวอย่างง่ายๆ นะครับ ถ้าไม่มี Context Manager:

# ไม่ใช้ Context Manager
f = open("my_config.txt", "w")
try:
    f.write("config_key=config_value")
    # สมมติเกิด error ตรงนี้
    1 / 0
finally:
    f.close() # ถ้าไม่ถึงตรงนี้ ไฟล์ก็ไม่ถูกปิด

โค้ดนี้ถ้าเกิด error ขึ้น ไฟล์ก็อาจจะยังเปิดค้างอยู่ได้นะครับ แต่ถ้าใช้ Context Manager มันจะจัดการให้เราอัตโนมัติเลยครับ ไม่ต้องห่วงเรื่อง close() เลย

# ใช้ Context Manager
with open("my_config.txt", "w") as f:
    f.write("config_key=config_value\
")
    f.write("another_key=another_value\
")
    # ลองให้เกิด error ดูครับ
    # 1 / 0
print("ไฟล์ถูกเขียนแล้วและปิดเรียบร้อยครับ!")

แบบนี้นะครับ มันจะมั่นใจได้เลยว่าไฟล์จะถูกปิดอัตโนมัติ ถึงแม้จะมี error เกิดขึ้นระหว่างทาง มันช่วยให้โค้ดเรามีความ Resilience ดีขึ้นเยอะเลยครับ

เพิ่ม Resilience ให้การจัดการไฟล์: Atomic Updates

บางทีเราต้องการ Update ไฟล์ config สำคัญๆ นะครับ แล้วถ้าเกิดระหว่างที่เราเขียนไฟล์ใหม่ ไฟดับ คอมค้าง หรือโค้ดพัง ไฟล์เก่าเราอาจจะเสียหาย ไฟล์ใหม่ก็ไม่สมบูรณ์ แบบนี้แย่เลยครับ

เราสามารถใช้เทคนิค "Atomic Update" แบบง่ายๆ ได้ครับ โดยการเขียนไปที่ไฟล์ชั่วคราว (temporary file) ก่อน แล้วค่อย Rename ไฟล์ชั่วคราวมาทับไฟล์เดิม ถ้ามีอะไรผิดพลาด เราก็ยังได้ไฟล์เก่าอยู่ครับ

นี่ครับ ตัวอย่างนะครับ:

import os
import tempfile

def update_config_safely(new_content, filename="app_config.json"):
    # สร้างไฟล์ชั่วคราว
    fd, temp_filepath = tempfile.mkstemp(dir=os.path.dirname(filename))

    try:
        with os.fdopen(fd, 'w') as tmp_file:
            tmp_file.write(new_content)

        # ถ้าเขียนไฟล์ชั่วคราวสำเร็จ ค่อย rename มาทับ
        os.replace(temp_filepath, filename)
        print(f"Update config '{filename}' สำเร็จแล้วครับ!")
    except Exception as e:
        print(f"เกิดข้อผิดพลาด: {e} | การ Update ถูกยกเลิกครับ!")
        # ถ้ามี error ก็ลบไฟล์ชั่วคราวทิ้งไป
        if os.path.exists(temp_filepath):
            os.remove(temp_filepath)
    finally:
        # ตรวจสอบอีกครั้งเพื่อความชัวร์
        if os.path.exists(temp_filepath):
            os.remove(temp_filepath) # Ensure temp file is cleaned up

# ลองใช้งานกันดูครับ
config_data = '{"database": "production", "version": "1.0"}'
update_config_safely(config_data, "my_app_config.json")

print("\
--- ลองแบบมี error ดูนะครับ ---")
try:
    # จะสร้าง error ในการเขียนไฟล์ชั่วคราว
    update_config_safely("invalid json here", "my_app_config.json")
    1 / 0 # ทำให้เกิด error อีก
except Exception:
    pass

แบบนี้ไฟล์ my_app_config.json ของเราก็จะปลอดภัยกว่าเยอะเลยครับ ถึงแม้โค้ดจะพังระหว่างทาง มันช่วยเพิ่ม Resilience ให้กับข้อมูลสำคัญของเรามากๆ เลย

ผนวกเข้ากับ Python CLI เพื่อ Optimization

เราเอาหลักการพวกนี้มาสร้างเป็น Python CLI (Command Line Interface) ของเราได้นะครับ เพื่อให้การจัดการไฟล์ต่างๆ ทำได้ง่ายและเป็นระบบมากขึ้น ลด Human Error ได้เยอะเลยครับ

นี่คือโครงสร้างง่ายๆ ของ CLI ที่ใช้ argparse นะครับ เพื่อสั่งให้ Update config ได้เลย:

import argparse
# import os
# import tempfile # ใช้จากตัวอย่างก่อนหน้า

# สมมติว่ามีฟังก์ชัน update_config_safely() อยู่แล้วจากด้านบน

def main():
    parser = argparse.ArgumentParser(description="เครื่องมือจัดการไฟล์ config อย่างปลอดภัย")
    parser.add_argument("command", choices=["update-config", "read-config"], help="คำสั่งที่ต้องการทำ")
    parser.add_argument("--file", default="app_config.json", help="ชื่อไฟล์ config ที่ต้องการจัดการ")
    parser.add_argument("--content", help="เนื้อหาใหม่สำหรับไฟล์ config (ใช้กับ update-config)")

    args = parser.parse_args()

    if args.command == "update-config":
        if not args.content:
            print("ต้องระบุ --content สำหรับคำสั่ง update-config ครับ!")
            return
        update_config_safely(args.content, args.file)
    elif args.command == "read-config":
        try:
            with open(args.file, 'r') as f:
                print(f"เนื้อหาของ '{args.file}':\
{f.read()}")
        except FileNotFoundError:
            print(f"ไม่พบไฟล์ '{args.file}' ครับ.")

if __name__ == "__main__":
    main()

# วิธีรันจาก Terminal:
# python your_cli_script.py update-config --file my_app_config.json --content '{"env": "dev"}'
# python your_cli_script.py read-config --file my_app_config.json

การทำ CLI แบบนี้ มันช่วย Optimize workflow ของเราได้ดีมากเลยครับ ไม่ต้องมานั่งเขียนโค้ดซ้ำๆ หรือเปิดไฟล์เองให้เสี่ยงผิดพลาด เรามีเครื่องมือช่วยจัดการได้เลย

สรุปนะครับ

การใช้ Context Manager เข้ามาช่วยในการ File Handling ร่วมกับการคิดเรื่อง Resilience ตั้งแต่แรก มันช่วยให้โค้ดของเรามั่นคงขึ้นเยอะเลยครับ แล้วพอเอามาทำเป็น Python CLI ก็ช่วย Optimization การทำงานของเรา ให้เราโฟกัสกับเรื่องที่สำคัญกว่าได้เต็มที่เลยครับ

เพื่อนๆ ลองเอาไปปรับใช้ในโปรเจกต์ของตัวเองดูนะครับ มันช่วยลดความปวดหัวได้เยอะจริงๆ ครับ

ไว้เจอกันใหม่บทความหน้านะครับ!

Read more

รมว.พลังงาน ปรับส่วนต่าง E20 ห่างโซฮอล์ 95 ลิตรละ 3 บาท กระตุ้นคนไทยใช้พลังงานสะอาด พร้อมขอความร่วมมือประหยัดไฟ

รมว.พลังงาน ปรับส่วนต่าง E20 ห่างโซฮอล์ 95 ลิตรละ 3 บาท กระตุ้นคนไทยใช้พลังงานสะอาด พร้อมขอความร่วมมือประหยัดไฟ

รมว.พลังงาน ประกาศปรับส่วนต่าง E20 ห่างโซฮอล์ 95 เป็น 3 บาท กระตุ้นใช้เชื้อเพลิงชีวภาพ พร้อมรณรงค์คนไทยประหยัดพลังงาน สร้างความมั่นคงพลังงานของชาติ

By ทีมงาน devdog
DMC: จากปรากฏการณ์ดนตรีระดับโลกสู่แสงธรรมนำทางชีวิต

DMC: จากปรากฏการณ์ดนตรีระดับโลกสู่แสงธรรมนำทางชีวิต

สำรวจสองความหมายสำคัญของ DMC! จาก Run-DMC ผู้บุกเบิกการร่วมงานฮิปฮอป-ร็อกที่พลิกโฉมวงการ สู่ dmc.tv ช่องธรรมะนำทางจิตใจเพื่อสันติสุขภายใน.

By ทีมงาน devdog
PM 2.5 กลับมาคลุ้ง! เปิด 12 อันดับค่าฝุ่นสูงสุดในกรุงเทพมหานคร

PM 2.5 กลับมาคลุ้ง! เปิด 12 อันดับค่าฝุ่นสูงสุดในกรุงเทพมหานคร

อัปเดตสถานการณ์ PM 2.5 ในกรุงเทพฯ ประจำวันที่ 10 มี.ค. 2569 พร้อมเปิด 12 เขตค่าฝุ่นสูงสุด และคำแนะนำป้องกันผลกระทบต่อสุขภาพ

By ทีมงาน devdog
One Piece Netflix ภาค 2: การผจญภัยสู่แกรนด์ไลน์ พร้อมกิจกรรมสุดอลังการที่สวนลุมฯ!

One Piece Netflix ภาค 2: การผจญภัยสู่แกรนด์ไลน์ พร้อมกิจกรรมสุดอลังการที่สวนลุมฯ!

One Piece Netflix ซีซัน 2 "มุ่งหน้าสู่แกรนด์ไลน์" เตรียมลงจอ 10 มี.ค. 2569 พร้อมกิจกรรม "GRAND LINE IN THAILAND" ที่สวนลุมพินี ห้ามพลาด!

By ทีมงาน devdog