แนวทางและเทคนิค

รวบรวมเทคนิคและรูปแบบที่ใช้บ่อยในการเขียนโปรแกรมด้วยภาษาปิยะธอน

การจัดการข้อมูล

การอ่านไฟล์แบบประหยัดหน่วยความจำ

นิยาม อ่านไฟล์ใหญ่(ชื่อไฟล์):
    """อ่านไฟล์ทีละบรรทัดเพื่อประหยัดหน่วยความจำ"""
    ด้วย เปิด(ชื่อไฟล์, 'r', encoding='utf-8') เป็น ไฟล์:
        สำหรับ บรรทัด ใน ไฟล์:
            ให้ บรรทัด.strip()

การจัดกลุ่มข้อมูล

จาก itertools นำเข้า groupby
จาก operator นำเข้า itemgetter

นิยาม จัดกลุ่มตามคีย์(ข้อมูล, คีย์):
    """จัดกลุ่มข้อมูลตามคีย์ที่กำหนด"""
    ข้อมูล = เรียงลำดับ(ข้อมูล, key=itemgetter(คีย์))
    คืนค่า {k: รายการ(v) สำหรับ k, v ใน groupby(ข้อมูล, key=itemgetter(คีย์))}

# ตัวอย่างการใช้งาน
ข้อมูล = [
    {'กลุ่ม': 'A', 'คะแนน': 80},
    {'กลุ่ม': 'B', 'คะแนน': 75},
    {'กลุ่ม': 'A', 'คะแนน': 90}
]
ผลลัพธ์ = จัดกลุ่มตามคีย์(ข้อมูล, 'กลุ่ม')

การแคชข้อมูล

จาก functools นำเข้า lru_cache

@lru_cache(maxsize=128)
นิยาม ดึงข้อมูล(id):
    """ดึงข้อมูลพร้อมแคช"""
    # จำลองการดึงข้อมูลจากฐานข้อมูล
    คืนค่า f"ข้อมูล: {id}"

# เรียกใช้ฟังก์ชัน - ครั้งแรกจะดึงข้อมูลจริง
ข้อมูล1 = ดึงข้อมูล(1)
# ครั้งต่อไปจะดึงจากแคช
ข้อมูล1_แคช = ดึงข้อมูล(1)

การจัดการข้อผิดพลาด

การสร้าง Context Manager

จาก contextlib นำเข้า contextmanager

@contextmanager
นิยาม จัดการทรัพยากร(ชื่อ):
    """จัดการการเปิด-ปิดทรัพยากรอัตโนมัติ"""
    พิมพ์(f"กำลังเปิด {ชื่อ}")
    ลอง:
        ให้ ชื่อ
    สุดท้าย:
        พิมพ์(f"กำลังปิด {ชื่อ}")

# ตัวอย่างการใช้งาน
ด้วย จัดการทรัพยากร("ไฟล์ทดสอบ") เป็น res:
    พิมพ์("กำลังใช้งานทรัพยากร")

การจัดการข้อผิดพลาดหลายประเภท

นิยาม ทำงานที่อาจผิดพลาด():
    """จัดการข้อผิดพลาดหลายประเภท"""
    ลอง:
        # โค้ดที่อาจเกิดข้อผิดพลาด
        ผลลัพธ์ = ทำงาน()
    ยกเว้น ValueError เป็น e:
        พิมพ์(f"ข้อมูลไม่ถูกต้อง: {e}")
    ยกเว้น TypeError เป็น e:
        พิมพ์(f"ชนิดข้อมูลไม่ถูกต้อง: {e}")
    ยกเว้น Exception เป็น e:
        พิมพ์(f"เกิดข้อผิดพลาด: {e}")
    อื่น:
        พิมพ์("ทำงานสำเร็จ")
    สุดท้าย:
        พิมพ์("เสร็จสิ้นการทำงาน")

การทำงานกับไฟล์

การหาไฟล์ทั้งหมดในโฟลเดอร์

จาก pathlib นำเข้า Path

นิยาม หาไฟล์(โฟลเดอร์, นามสกุล="*"):
    """หาไฟล์ทั้งหมดในโฟลเดอร์และโฟลเดอร์ย่อย"""
    พาธ = Path(โฟลเดอร์)
    คืนค่า รายการ(พาธ.rglob(f"*.{นามสกุล}"))

# ตัวอย่างการใช้งาน
ไฟล์_py = หาไฟล์("src", "py")
สำหรับ ไฟล์ ใน ไฟล์_py:
    พิมพ์(ไฟล์)

การประมวลผลไฟล์ CSV แบบ Streaming

นำเข้า csv
จาก itertools นำเข้า islice

นิยาม ประมวลผล_csv(ชื่อไฟล์, ขนาด_batch=1000):
    """ประมวลผลไฟล์ CSV ทีละส่วน"""
    ด้วย เปิด(ชื่อไฟล์, newline='', encoding='utf-8') เป็น csvfile:
        reader = csv.DictReader(csvfile)
        ขณะที่ จริง:
            batch = รายการ(islice(reader, ขนาด_batch))
            ถ้า ไม่ batch:
                หยุด
            ให้ batch

การทำงานกับเวลา

การวัดเวลาทำงาน

จาก time นำเข้า perf_counter
จาก functools นำเข้า wraps

นิยาม จับเวลา(func):
    """เดคอเรเตอร์สำหรับวัดเวลาทำงานของฟังก์ชัน"""
    @wraps(func)
    นิยาม wrapper(*args, **kwargs):
        เริ่ม = perf_counter()
        ผลลัพธ์ = func(*args, **kwargs)
        สิ้นสุด = perf_counter()
        พิมพ์(f"{func.__name__} ใช้เวลา {สิ้นสุด - เริ่ม:.4f} วินาที")
        คืนค่า ผลลัพธ์
    คืนค่า wrapper

# ตัวอย่างการใช้งาน
@จับเวลา
นิยาม ทำงานนาน():
    จาก time นำเข้า sleep
    sleep(1)

การจัดการเขตเวลา

จาก datetime นำเข้า datetime
จาก zoneinfo นำเข้า ZoneInfo

นิยาม แปลงเขตเวลา(เวลา, จาก_โซน, ไป_โซน):
    """แปลงเวลาระหว่างเขตเวลา"""
    เวลา_ต้นทาง = เวลา.replace(tzinfo=ZoneInfo(จาก_โซน))
    คืนค่า เวลา_ต้นทาง.astimezone(ZoneInfo(ไป_โซน))

# ตัวอย่างการใช้งาน
เวลา = datetime.now()
เวลา_ไทย = แปลงเขตเวลา(เวลา, "UTC", "Asia/Bangkok")

เทคนิคการเขียนโค้ด

การใช้ Generator

นิยาม อ่านทีละบรรทัด(ไฟล์):
    """Generator สำหรับอ่านไฟล์ทีละบรรทัด"""
    ด้วย เปิด(ไฟล์, 'r', encoding='utf-8') เป็น f:
        สำหรับ บรรทัด ใน f:
            ให้ บรรทัด.strip()

# ตัวอย่างการใช้งาน
สำหรับ บรรทัด ใน อ่านทีละบรรทัด('ไฟล์.txt'):
    พิมพ์(บรรทัด)

การทำงานแบบขนาน

จาก concurrent.futures นำเข้า ThreadPoolExecutor, ProcessPoolExecutor

นิยาม ประมวลผลขนาน(ข้อมูล, func, ประเภท='thread', max_workers=4):
    """ประมวลผลข้อมูลแบบขนาน"""
    Executor = ThreadPoolExecutor ถ้า ประเภท == 'thread' อื่น ProcessPoolExecutor

    ด้วย Executor(max_workers=max_workers) เป็น executor:
        ผลลัพธ์ = รายการ(executor.map(func, ข้อมูล))

    คืนค่า ผลลัพธ์

# ตัวอย่างการใช้งาน
นิยาม ทำงาน(x):
    คืนค่า x * x

ข้อมูล = ช่วง(10)
ผลลัพธ์ = ประมวลผลขนาน(ข้อมูล, ทำงาน)

การทดสอบ

การเขียนเทสต์

จาก unittest นำเข้า TestCase, main
จาก unittest.mock นำเข้า Mock, patch

ชั้น ทดสอบการทำงาน(TestCase):
    นิยาม setUp(ตัว):
        ตัว.ข้อมูล = {'id': 1, 'ชื่อ': 'ทดสอบ'}

    นิยาม test_การคำนวณ(ตัว):
        ผลลัพธ์ = คำนวณ(ตัว.ข้อมูล)
        ตัว.assertEqual(ผลลัพธ์, 1)

    @patch('module.external_api')
    นิยาม test_เรียก_api(ตัว, mock_api):
        mock_api.return_value = {'status': 'ok'}
        ผลลัพธ์ = เรียก_api()
        ตัว.assertEqual(ผลลัพธ์['status'], 'ok')

ถ้า __ชื่อ__ == '__main__':
    main()

Note

เทคนิคและรูปแบบเหล่านี้สามารถนำไปประยุกต์ใช้กับโค้ดของคุณ โดยปรับแต่งให้เหมาะสมกับความต้องการเฉพาะได้