Nuitka: ปั้น Python เป็น EXE แจกจ่ายแอปแบบไม่ต้องคิดมาก
วันนี้มาคุยเรื่อง Nuitka กันหน่อยครับ
คือบางทีเราเขียน Python แล้วมันต้องเอาไปให้คนอื่นใช้ไง พวก user ทั่วไปงี้ ซึ่งส่วนใหญ่ก็ไม่ได้ลง Python กันอยู่แล้วป่ะ?
ทางออกคือก็ต้องแปลงเป็นไฟล์ .exe หรือ binary สำหรับ OS นั้นๆ ให้มันรันได้เลย คือให้มันกดดับเบิ้ลคลิกแล้วรันได้เลยงี้
หลายคนคงเคยได้ยิน PyInstaller หรือ cx_Freeze มาบ้าง แต่ Nuitka เนี่ยมันเจ๋งตรงที่มันเป็น compiler เลยนะ ไม่ใช่แค่ packager เฉยๆ
มันพยายามจะคอมไพล์โค้ด Python เราให้เป็น C code แล้วค่อยคอมไพล์ C นั้นเป็น binary อีกที ซึ่งบางเคสเร็วกว่าด้วยนะ ลองดูสิ!
วิธีใช้ Nuitka แบบง่ายๆ
วิธีใช้ก็ไม่ได้ยากมากนะ ติดตั้ง Nuitka ก่อน
pip install Nuitka
แล้วก็สั่งคอมไพล์เลย สมมติเรามีไฟล์ my_app.py อยู่
nuitka --standalone my_app.py
แค่นี้? ใช่ แค่นี้แหละ! มันจะสร้างโฟลเดอร์ my_app.dist ขึ้นมา ข้างในก็จะมีไฟล์ my_app.exe (หรือ binary บน Linux/Mac) พร้อมพวก DLL/shared libs ที่จำเป็น
ตัว --standalone สำคัญนะ เพราะมันจะพยายามรวมทุกอย่างที่จำเป็นให้มาอยู่ด้วยกัน ให้ไฟล์ที่ได้รันได้เดี่ยวๆ เลย
ปัญหาที่เจอบ่อย (Gotchas!) และวิธีแก้
แต่ชีวิตมันก็ไม่ง่ายขนาดนั้นไงล่ะ! บางทีเจอ Error แบบรันไม่ได้ หรือ Missing Module อะไรเทือกๆ เนี้ย
Error ตัวอย่าง 1: รันไม่ได้บน Windows (Missing VCRUNTIME140.dll)
อันนี้โคตรเจอบ่อย! คือ Nuitka มันอาจจะใช้ MSVC ในการคอมไพล์ แล้วบางเครื่องไม่มี Visual C++ Redistributable Package มันก็ฟ้องหา VCRUNTIME140.dll บ่อยๆ เลย
วิธีแก้: ก็ไปดาวน์โหลด Visual C++ Redistributable จากเว็บ Microsoft มาลงซะ ก็จบครับ หรือหาใน Google พิมพ์ VCRUNTIME140.dll download ก็เจอ
หรือถ้า Nuitka มันยังพังอีก อาจจะต้องลองลง pip install pypiwin32 บางทีก็ช่วยได้นะ สำหรับ Windows
Error ตัวอย่าง 2: ModuleNotFoundError ตอนรัน (ลืม include บางอย่าง)
บางทีเราใช้ library ที่ Nuitka มัน detect ไม่เจอ หรือมีไฟล์ข้อมูล (images, configs) ที่เราต้องพกไปด้วย สมมติโค้ดเราใช้ requests แต่ Nuitka ไม่ได้รวมมาให้ (ซึ่งปกติมันจะรวมนะ แต่อาจมีเคสแปลกๆ)
หรือไม่ก็เรามีไฟล์ config.json อยู่ข้างๆ my_app.py แล้วในโค้ดอ่านไฟล์นี้
# my_app.py
import json
import requests # สมมติว่าใช้ library requests
try:
with open('config.json', 'r') as f:
config = json.load(f)
print("Loaded config:", config)
except FileNotFoundError:
print("config.json not found!")
config = {}
print("\nFetching example data from an API...")
try:
response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
print("API data:", response.json())
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
input("\nPress Enter to exit...")
ถ้ามี config.json ด้วย ก็ต้องสั่งแบบนี้
nuitka --standalone --include-data-file=config.json=config.json my_app.py
# ถ้าเป็นโฟลเดอร์ข้อมูลทั้งโฟลเดอร์เลย:
# nuitka --standalone --include-data-dir=my_data_folder=my_data_folder my_app.py
ตัว requests เนี่ย ปกติ Nuitka มันจัดการให้ได้อยู่แล้ว แต่ถ้าเป็น library แปลกๆ หรือพวกที่ใช้ dynamic import หนักๆ หรือที่ Nuitka มันหาไม่เจอจริงๆ ก็อาจจะต้องใช้ --follow-imports หรือ --include-package เข้ามาช่วย
เช่น --include-package=requests ถ้ามันไม่ยอมรวมมาให้ หรือ --include-package=PIL สำหรับ Pillow.
คือต้องทดลองดูโคตรเยอะเลยนะบางที! แต่ก็ถือว่าคุ้มถ้าต้องแจกให้ user เขาใช้แบบง่ายๆ
โหมด Onefile (ไฟล์เดียวจบ)
อีกโหมดที่คนชอบคือ --onefile มันจะบีบทุกอย่างให้อยู่ในไฟล์เดียวเลย my_app.exe ไฟล์เดียวจริงๆ
nuitka --onefile --standalone my_app.py
แต่ข้อเสียคือตอนรันมันจะแตกไฟล์ชั่วคราวออกมา แล้วค่อยรัน ซึ่งบางทีก็ช้ากว่า และ Antivirus บางตัวอาจจะมองว่าน่าสงสัยได้นะ เพราะมันเหมือนโปรแกรมที่แตกไฟล์ตัวเองออกมา
ส่วนตัวไม่ค่อยแนะนำ --onefile ถ้าไม่จำเป็นจริงๆ เพราะมันสร้างปัญหาจุกจิกกว่าเยอะ อย่างเช่น ไฟล์ใหญ่มาก หรือถูก Antivirus บล็อค
สรุปและความคิดเห็นส่วนตัว
Nuitka นี่มันเหมาะกับงานที่เป็นเครื่องมือเล็กๆ ที่เราอยากแจกให้คนอื่นใช้แบบไม่ต้องลง Python หรือถ้าเป็นโปรเจกต์ที่ต้องการ performance ดีกว่า PyInstaller หน่อย.
สำหรับโปรเจกต์ใหญ่ๆ ซับซ้อนๆ บางทีก็ปวดหัวกับมันนะ Dependency มันเยอะไปหมด มันอาจจะหาไม่เจอ หรือโค้ดเราใช้เทคนิคแปลกๆ อย่าง eval() หรือ exec() เนี่ย Nuitka ก็งงๆ ไม่รู้จะคอมไพล์ยังไง.
ถ้าเจอ Error จุกจิก แนะนำให้ลองรันโดยไม่ใช้ --onefile ก่อน แล้วค่อยๆ debug ดูว่าไฟล์ไหนหายไปจากโฟลเดอร์ dist (ที่มันสร้างมานั่นแหละ).
ข้อดีสุดๆ คือ Nuitka มันทำให้โค้ดเรา obfuscate ขึ้นด้วยนะ คือยากที่จะ decompile กลับมาเป็น Python เหมือนเดิมได้ง่ายๆ เพราะมันกลายเป็น C binary ไปแล้ว.
ก็ประมาณนี้แหละ Nuitka ลองเอาไปใช้ดูนะ ถ้าต้องแจก Python app ให้คนอื่นใช้แล้วไม่อยากให้เขาต้องลง Python เอง หรืออยากให้โปรแกรมมันดูเป็นโปรแกรมจริงๆ ไม่ใช่แค่สคริปต์ Python.