2010-07-15 36 views
6

Ứng dụng Python của tôi được xây dựng sao cho một số chức năng có sẵn dưới dạng bổ trợ. Kiến trúc plugin hiện tại rất đơn giản: Tôi có một thư mục/gói bổ sung chứa một số mô đun python. Tôi tải plugin liên quan như sau:Tải động các plugin trăn chưa được biên dịch trong mã biên dịch py2exe

plugin_name = blablabla 
try: 
    module = __import__(plugin_name, fromlist='do_something') 
except ImportError: 
    #some error handling ... 

và sau đó thực hiện:

try: 
    loans = module.do_something(id_t, pin_t) 
except xxx: 
    # error handling 

tôi biên dịch các ứng dụng để Windows nhị phân sử dụng py2exe. Điều này làm việc tốt, ngoại trừ thực tế là tất cả các plugin (và phải) được bao gồm trong nhị phân. Điều này không thực tế lắm, vì đối với mỗi plugin mới, tôi phải biên dịch lại và phát hành phiên bản mới của ứng dụng. Sẽ tốt hơn nếu một plugin mới (tức là tệp python) có thể được sao chép vào một số thư mục plugin ứng dụng và mã Python trong mã tệp được diễn giải trực tiếp bởi ứng dụng của tôi.

Cách tiếp cận tốt nhất để làm như vậy là gì?

(Tôi đã mặc dù đọc từng dòng của file plugin chọn, và áp dụng một exec statement với nó. Nhưng có thể có những cách tốt hơn ...)

Trả lời

0

tôi đề nghị bạn sử dụng tính năng pkg_resources entry_points (từ setuptools/phân phối) để triển khai phát hiện và khởi tạo plugin: đầu tiên, đó là cách tiêu chuẩn để thực hiện điều đó; thứ hai, nó không bị vấn đề bạn đề cập đến AFAIK. Tất cả những gì bạn cần làm để mở rộng ứng dụng là đóng gói một số phần bổ trợ vào trứng để khai báo một số điểm vào (trứng có thể khai báo nhiều plugin) và khi bạn cài đặt trứng đó vào phân phối python của bạn, tất cả các plugin được khai báo có thể tự động được ứng dụng của bạn phát hiện. Bạn cũng có thể đóng gói ứng dụng của bạn và các plugin "nhà máy" vào cùng một quả trứng, nó khá thuận tiện.

+1

Cảm ơn câu trả lời. Nhưng điều này không đòi hỏi ai đó phải cài đặt python trên máy tính của anh ta? (giải pháp tôi đề xuất, sẽ yêu cầu điều đó, bây giờ tôi nghĩ về nó) – Rabarberski

+0

Bạn nói đúng, nó phải là cùng một cài đặt python cho cả ứng dụng của bạn và các plugin bên ngoài. Tôi đồng ý điều này khá khó chịu. –

0

Tôi không chắc chắn bạn phải đặt các tệp plugin trong thư viện zip. Điều này có thể là do bạn đang sử dụng mặc định để đóng gói py2exe tập lệnh của bạn.

Bạn có thể thử sử dụng nén = False (như được ghi trong py2exe ListOfOptions) sẽ loại bỏ thư viện.zip được tạo bởi py2exe và có thể cho phép bạn truy cập vào mô-đun python (plugin của bạn là các mô-đun python, tôi đoán, từ nhập) theo cách "bình thường", thay vì buộc phải đóng gói chúng trong mã zip hoặc nhị phân của bạn.

1

PyInstaller cũng cho phép bạn nhập tệp bên ngoài. Nếu bạn chạy nó trên ứng dụng của mình, nó sẽ không đóng gói các tệp đó trong tệp thực thi. Sau đó bạn sẽ phải đảm bảo rằng đường dẫn là chính xác (nghĩa là, ứng dụng của bạn có thể tìm thấy các mô-đun trên đĩa trong thư mục chính xác) và mọi thứ sẽ hoạt động.

2

Nếu bạn không nhớ rằng plugin sẽ được phát hành dưới dạng tệp .py, bạn có thể thực hiện một số việc như sau. Đặt tất cả các plugin của bạn dưới một "plugin" subdir, và tạo ra một "__init__.py" rỗng. Làm thời gian chạy, nó sẽ nhập gói cùng với tất cả các mô-đun trong thư mục đó. Kiểm tra Dive In Python để được giải thích ... nhưng đây là những gì tôi cuối cùng sẽ sử dụng.

def load_plugin(path): 
    import imp 
    """Load plugin from directory and return list of modules""" 
    files = os.listdir(path) 
    test = re.compile(".py$", re.IGNORECASE)   
    files = filter(test.search, files)      
    filenameToModuleName = lambda f: os.path.splitext(f)[0] 
    moduleNames = sorted(map(filenameToModuleName, files)) 
    f, filename, desc = imp.find_module('plugin') 
    plugin = imp.load_module('plugin', f, filename, desc) 
    modules = [] 

    #print moduleNames 
    for m in moduleNames: 
     # skip any files starting with '__', such as __init__.py 
     if m.startswith('__'): 
      continue 
     try: 
      f, filename, desc = imp.find_module(m, plugin.__path__) 
      modules.append(imp.load_module(m, f, filename, desc)) 
     except ImportError: 
      continue 
    return modules 
+0

Có thể cho các mô-đun đó tải các Lớp tồn tại trong phiên bản đã biên dịch không? –

0

Tôi tìm thấy cách nhập mô-đun bên ngoài (trên đầu trang của tệp thực thi được biên dịch, lúc chạy) với pyinstaller. nó con số ban đầu, đường dẫn của tệp thực thi được tự động thêm vào sys.path, nhưng vì lý do bảo mật, chúng loại bỏ điều này tại một số điểm. để kích hoạt lại này, sử dụng:

sys.path.append(os.path.dirname(sys.executable)) 

này sẽ cho phép nhập khẩu py file mà ngồi trong đường dẫn giống như thực thi. bạn có thể thêm dòng này vào móc thời gian chạy hoặc ứng dụng chính.

Các vấn đề liên quan