Cách thực hiện tải plugin trong chương trình Python (tải mô-đun động, phát triển theo kiến trúc plugin)
Trong thế giới lập trình ngày nay, việc mở rộng tính năng của phần mềm thông qua các plugin hoặc mô-đun phụ là một xu hướng phổ biến. Nhiều công cụ như PyCharm, VSCode đều hỗ trợ thêm plugin để mở rộng chức năng. Trò chơi nổi tiếng như Minecraft, Terraria hay Don’t Starve cũng cho phép người dùng tùy chỉnh trải nghiệm bằng cách thêm mod.
Python, với định dạng module chính là .py (hoặc .pyd), mang lại sự tiện lợi đáng kể khi làm việc với các mô-đun và plugin. Vậy làm thế nào để tạo ra một hệ thống có khả năng quét và tải plugin trong Python?
Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách:
- Tải mô-đun một cách động.
- Nhập mô-đun từ các vị trí cụ thể (tương đối hoặc tuyệt đối).
- Khiến chương trình có thể tìm thấy các mô-đun cần tải.
Phần 1: Làm thế nào để tải mô-đun một cách động
1.1 Sử dụng từ khóa import
(Không khả thi)
Phương pháp sử dụng từ khóa import
và from
là cách phổ biến nhất để nhập mô-đun trong Python. Tuy nhiên, tên mô-đun sau từ khóa không thể là biến mà phải là hằng số đã được xác định trước. Điều này khiến việc sử dụng các công cụ đóng gói như PyInstaller hoặc Nuitka trở nên khó khăn hơn nếu bạn cố gắng để trống tên mô-đun sau từ khóa.
1.2 Sử dụng hàm __import__
(Không khuyến khích)
Hàm __import__
thực chất là phiên bản gốc của import
, nhưng Python không khuyến khích sử dụng nó. Thay vào đó, Python khuyến nghị sử dụng importlib.import_module
.
1.3 Sử dụng mô-đun importlib
Mô-đun importlib
cung cấp một cách đơn giản và hiệu quả để tải mô-đun động. Hàm importlib.import_module(name, package=None)
chỉ yêu cầu hai tham số: tên mô-đun và tên gói (nếu có). Bạn cũng có thể sử dụng cú pháp tương đối như ".aaa.aaa"
khi chỉ định tham số package
.
Lưu ý rằng khi sử dụng đường dẫn tương đối, hãy chú ý đến vị trí chạy của tệp thực thi (như .exe
) vì đây sẽ là điểm khởi đầu cho đường dẫn tương đối.
Phần 2: Nhập mô-đun từ vị trí cụ thể
Giả sử cấu trúc thư mục của dự án như sau:
|
|
2.1 Nhập mô-đun từ cùng cấp hoặc cấp dưới
Khi tệp __main__1.py
là điểm nhập:
|
|
2.2 Nhập mô-đun từ cấp trên
Khi tệp __main__2.py
là điểm nhập:
2.2.1 Sử dụng từ khóa from ... import
(Không giải quyết được)
Nếu thử nhập từ cấp trên như sau:
|
|
Bạn sẽ gặp lỗi ImportError: attempted relative import with no known parent package
. Nguyên nhân là do __main__2.py
không thuộc về một gói cụ thể mà là chương trình chính.
2.2.2 Sử dụng sys.path
sys.path
hoạt động giống như biến môi trường trong Windows, chứa danh sách các vị trí mà Python sẽ tìm kiếm các gói. Để nhập mô-đun từ cấp trên, bạn chỉ cần thêm đường dẫn cấp trên vào danh sách sys.path
:
|
|
2.2.3 Ví dụ thực tế
|
|
Phần 3: Khiến chương trình có thể tìm thấy các plugin
Có nhiều cách để quản lý và tìm kiếm các plugin. Python cung cấp các mô-đun tích hợp như os.path
và pathlib
để xử lý file và thư mục.
Quy tắc plugin đơn giản
Để dễ dàng triển khai, chúng ta sẽ áp dụng quy tắc sau: mọi tệp có đuôi .py nằm trong thư mục plugins đều được coi là plugin hợp lệ.
Quy trình cơ bản:
- Quét tất cả các tệp trong thư mục plugins.
- Lọc ra các tệp có đuôi .py.
- Chuyển đổi tên tệp thành định dạng phù hợp để truyền vào
importlib.import_module()
.
Ví dụ mã nguồn:
|
|
Ví dụ hoàn chỉnh
Cấu trúc thư mục
|
|
Trong đó module1.py
và module2.py
là hai plugin.
Nội dung module1.py
|
|
Nội dung main_program/__main__.py
|
|
Tổng kết
Bài viết đã trình bày cách triển khai hệ thống plugin trong Python bằng cách sử dụng importlib
để tải mô-đun động và os.path
để quản lý file/thư mục. Với phương pháp này, bạn có thể dễ dàng xây dựng các ứng dụng có khả năng mở rộng cao.
Hy vọng bài viết này hữu ích cho bạn!