Kiều Mạnh
I don't program, I beat code into submission!!!
- Tham gia
- 9/6/12
- Bài viết
- 5,701
- Được thích
- 4,188
- Giới tính
- Nam
Mình vốn quen làm việc chính với Delphi/C++ Builder và Go để viết add-in Excel,
nhưng gần đây có thử nghiệm thêm hướng dùng Python để xử lý logic, sau đó biên dịch thành mã máy (không phải file .py gốc) nhằm mục đích:
Sau vài lần thử, mình có 1 quy trình nhỏ chạy ổn, chia sẻ lại để các bác tham khảo, đồng thời rất mong nghe thêm cách các bác đang làm - chắc chắn còn nhiều hướng hay hơn mình chưa biết.
File .pyx viết gần giống hệt Python thường, chỉ khác đây là biến thể có thể biên dịch ra C:
def cong(a, b):
return a + b
def tinh_gia_sau_giam(gia_goc, phan_tram_giam):
if phan_tram_giam < 0 or phan_tram_giam > 100:
raise ValueError("Phan tram giam phai tu 0 den 100")
return gia_goc * (1 - phan_tram_giam / 100)
Bước 2 - Biên dịch .pyx → .pyd
Cần cài Cython + Visual Studio Build Tools (chỉ cần workload "Desktop development with C++", không cần cài cả bộ Visual Studio). Sau đó chạy:
python setup.py build_ext --inplace
Kết quả ra file xu_ly_logic.pyd - đây thực chất là 1 file DLL đã biên dịch thành mã máy x64, không còn là code Python đọc được nữa (khác hẳn .pyc, không decompile ngược ra Python gốc được bằng công cụ thông thường).
Bước 3 - Đóng gói tiếp thành .exe độc lập (không cần cài Python)
Dùng PyInstaller để gộp Python runtime + file .pyd thành 1 file .exe duy nhất:
pyinstaller --onefile --add-binary "xu_ly_logic.pyd;." --name ChuongTrinhDemo main.py
File .exe này copy sang máy khác chạy thẳng, máy đích không cần cài Python.
Mình gửi kèm bộ demo đầy đủ trong file zip, gồm:
Ai muốn tự build lại thì cần cài sẵn Python + Cython + PyInstaller + Visual Studio Build Tools trên máy, sau đó chạy build_exe.bat.
Cảm ơn các bạn đã đọc, mong nhận được góp ý và các hướng làm khác để mình học hỏi thêm!
File đính kèm: pyd_exe_demo.zip
nhưng gần đây có thử nghiệm thêm hướng dùng Python để xử lý logic, sau đó biên dịch thành mã máy (không phải file .py gốc) nhằm mục đích:
- Tăng tốc độ xử lý so với chạy Python thông thường (interpreter thuần)
- Ẩn source code gốc - không muốn phát tán file .py để người khác đọc/copy logic
- Có thể đóng gói thành .exe chạy độc lập, không cần máy đích cài Python
Sau vài lần thử, mình có 1 quy trình nhỏ chạy ổn, chia sẻ lại để các bác tham khảo, đồng thời rất mong nghe thêm cách các bác đang làm - chắc chắn còn nhiều hướng hay hơn mình chưa biết.
Quy trình mình đang dùng
Bước 1 - Viết logic bằng Cython (.pyx)File .pyx viết gần giống hệt Python thường, chỉ khác đây là biến thể có thể biên dịch ra C:
def cong(a, b):
return a + b
def tinh_gia_sau_giam(gia_goc, phan_tram_giam):
if phan_tram_giam < 0 or phan_tram_giam > 100:
raise ValueError("Phan tram giam phai tu 0 den 100")
return gia_goc * (1 - phan_tram_giam / 100)
Bước 2 - Biên dịch .pyx → .pyd
Cần cài Cython + Visual Studio Build Tools (chỉ cần workload "Desktop development with C++", không cần cài cả bộ Visual Studio). Sau đó chạy:
python setup.py build_ext --inplace
Kết quả ra file xu_ly_logic.pyd - đây thực chất là 1 file DLL đã biên dịch thành mã máy x64, không còn là code Python đọc được nữa (khác hẳn .pyc, không decompile ngược ra Python gốc được bằng công cụ thông thường).
Bước 3 - Đóng gói tiếp thành .exe độc lập (không cần cài Python)
Dùng PyInstaller để gộp Python runtime + file .pyd thành 1 file .exe duy nhất:
pyinstaller --onefile --add-binary "xu_ly_logic.pyd;." --name ChuongTrinhDemo main.py
File .exe này copy sang máy khác chạy thẳng, máy đích không cần cài Python.
File đính kèm
Mình gửi kèm bộ demo đầy đủ trong file zip, gồm:
- xu_ly_logic.pyd - module đã biên dịch sẵn (5 hàm: cộng, trừ, nhân, chia, tính giá sau giảm)
- main.py - chương trình demo gọi vào module trên
- build_exe.bat - chạy tự động lệnh PyInstaller đóng gói .exe
- run_exe.bat - chạy thử file .exe sau khi build
Ai muốn tự build lại thì cần cài sẵn Python + Cython + PyInstaller + Visual Studio Build Tools trên máy, sau đó chạy build_exe.bat.
Vài điều mình còn băn khoăn, mong các bạn góp ý
- Cách này chỉ hợp khi muốn giấu logic tính toán khỏi Python thuần, nhưng nếu muốn tái sử dụng cho Delphi/VB6/VBA gọi trực tiếp thì file .pyd này lại không dùng trực tiếp được (chỉ export hàm PyInit_... dành riêng cho CPython nạp module, không theo chuẩn C-ABI thường). Các bác nào từng làm việc này có kinh nghiệm gì cross-language giữa Python và Delphi/VBA không?
- Có bác nào đã thử dùng Python làm COM server (qua pywin32) để Excel/VBA gọi vào bằng CreateObject chưa? Mình nghe nói cách này khả thi nhưng chưa thử, không rõ độ ổn định và tốc độ thực tế so với add-in Delphi/XLL truyền thống thế nào.
- Nếu ai có kinh nghiệm với PyXLL hoặc xlwings để làm add-in hàm số Excel bằng Python thật sự (không qua trung gian DLL/EXE), rất mong chia sẻ thêm góc nhìn, ưu nhược điểm so với cách viết Add-in bằng Delphi/C++ Builder truyền thống.
Cảm ơn các bạn đã đọc, mong nhận được góp ý và các hướng làm khác để mình học hỏi thêm!
File đính kèm: pyd_exe_demo.zip