2011-07-04 10 views
5

Tôi đã tự hỏi làm thế nào tôi có thể cung cấp một API cho chương trình Python của tôi để cho phép những người khác mở rộng nó bằng các plugin. Tôi đã nghĩ về điều gì đó như from myProgram.plugins import aClassToExtendByOthers, registerThatClass. Nhưng tôi không có ý tưởng làm thế nào để cung cấp này.Làm thế nào để cung cấp một API để mở rộng một chương trình Python với các plugin?

Tôi có thể sử dụng câu lệnh exec trong hàm loadPlugins cho mọi plugin trong thư mục plugin nhưng điều này sẽ không cho phép nhập nội dung tôi muốn cung cấp cho mọi người viết các plugin đó.

+0

Dưới đây là [nhiều cách] (http : //zoomq.qiniudn.com/ZQScrapBook/ZqFLOSS/data/20060526140550/#command-dispatch-pattern) để triển khai mẫu gửi lệnh trong Python. – martineau

Trả lời

2

Đối với hệ thống mà tôi sử dụng trong một số chương trình của mình, tôi xác định thư mục bổ trợ và cung cấp lớp plugin cơ sở cho tất cả các plugin cho lớp con. Sau đó, tôi nhập tất cả các mô-đun trong thư mục và khởi tạo có chọn lọc (bằng cách kiểm tra xem chúng có phân lớp lớp plugin cơ sở của tôi) hay không và lưu trữ các bổ sung trong từ điển (hoặc danh sách). Tôi đã tìm thấy rằng command dispatch pattern đã hoạt động hiệu quả đối với tôi như một cách để cấu trúc các plugin và truyền sự kiện. Plugin cơ sở (hoặc một lớp giao diện tùy chọn khác) có thể cung cấp các phương thức mà plugin cần tương tác với ứng dụng. Tôi hi vọng cái này giúp được. Nó có thể không phải là cách tốt nhất để làm điều đó, nhưng nó đã làm việc cho tôi.

Ngoài ra, bạn có thể thực hiện lọc bổ sung, chẳng hạn như yêu cầu tệp plugin để có tiền tố (ví dụ: __plug_file.py____plug_other.py__).

+0

Vì vậy, bạn chỉ cần sử dụng một tuyên bố exec hoặc tôi đã hiểu bạn sai? –

+0

Không, tôi nhập khẩu các mô-đun bằng cách sử dụng hàm _ _ \ _ import \ _ \ _, và sau đó sử dụng kiểm tra để liệt kê tất cả các lớp trong mô-đun mà tôi vừa mới nhập vào. Hệ thống này cho phép các plugin sử dụng các mô-đun khác, mà bạn đã nói là một trong những mối quan tâm của bạn. Chỉ cần sử dụng exec trong những trường hợp này có thể nguy hiểm. –

+0

Hm, chắc chắn điều này tốt hơn so với exec. Nhưng làm thế nào để tôi cung cấp rằng các biên tập viên có thể sử dụng các lớp tôi cung cấp cho anh ta bằng cách nhập chúng? (như đã nói trong câu hỏi giống như _from myProgram.plugins import extensiblePluginClass_) –

0

bạn có thể sử dụng mô-đun imp (xem docs.python.org)

sys.path.insert(0, pluginsDir) 
lst = map(lambda x: os.path.splitext(os.path.basename(x))[0], glob.glob(os.path.join(pluginsDir, "*.py"))) 
for module in lst: 
try: 
    f, fn, d = imp.find_module(module,[pluginsDir]) 
    loaded = imp.load_module(module, f, fn, d) 

ví dụ đầy đủ chức năng xem các bộ nạp của ojuba trung tâm điều khiển

http://git.ojuba.org/cgit/occ/tree/OjubaControlCenter/loader.py