2009-02-18 26 views
18

Tôi đang viết một phần mềm trên github. Nó về cơ bản là một biểu tượng khay với một số tính năng bổ sung. Tôi muốn cung cấp một đoạn mã hoạt động mà không cần phải cài đặt người dùng về cơ bản phụ thuộc vào các tính năng tùy chọn và tôi không thực sự muốn nhập những thứ tôi sẽ không sử dụng vì vậy tôi nghĩ mã như thế này sẽ là " giải pháp tốt ":Thực tiễn tốt về Python để nhập và cung cấp các tính năng tùy chọn là gì?

---- IN LOADING FUNCTION ---- 
features = [] 

for path in sys.path: 
     if os.path.exists(os.path.join(path, 'pynotify')): 
       features.append('pynotify') 
     if os.path.exists(os.path.join(path, 'gnomekeyring.so')): 
       features.append('gnome-keyring') 

#user dialog to ask for stuff 
#notifications available, do you want them enabled? 
dlg = ConfigDialog(features) 

if not dlg.get_notifications(): 
    features.remove('pynotify') 


service_start(features ...) 

---- SOMEWHERE ELSE ------ 

def service_start(features, other_config): 

     if 'pynotify' in features: 
       import pynotify 
       #use pynotify... 

Tuy nhiên, có một số vấn đề. Nếu người dùng định dạng máy của mình và cài đặt phiên bản mới nhất của hệ điều hành của anh ấy và redeploys ứng dụng này, các tính năng đột nhiên biến mất mà không cần cảnh báo. Giải pháp là để trình bày này trên cửa sổ cấu hình:

if 'pynotify' in features: 
    #gtk checkbox 
else: 
    #gtk label reading "Get pynotify and enjoy notification pop ups!" 

Nhưng nếu điều này là nói, một mac, làm thế nào để tôi biết tôi sẽ không gửi người dùng trên một đuổi ngỗng hoang dã tìm kiếm một sự phụ thuộc họ có thể không bao giờ lấp đầy?

Vấn đề thứ hai là: Vấn đề

if os.path.exists(os.path.join(path, 'gnomekeyring.so')): 

. Tôi có thể chắc chắn rằng các tập tin luôn được gọi là gnomekeyring.so trên tất cả các distro linux?

Làm cách nào để những người khác kiểm tra các tính năng này? Vấn đề với các mã cơ bản

try: 
    import pynotify 
except: 
    pynotify = disabled 

là mã toàn cục, mã này có thể được rải rác xung quanh và ngay cả khi người dùng không muốn pynotify .... nó vẫn được tải.

Vậy mọi người nghĩ gì là cách tốt nhất để giải quyết vấn đề này?

Trả lời

10

Bạn có thể muốn xem qua số imp module, về cơ bản bạn sẽ làm những gì bạn làm theo cách thủ công ở trên. Vì vậy, trước tiên bạn có thể tìm kiếm một mô-đun với find_module() và sau đó tải nó qua load_module() hoặc đơn giản là nhập nó (sau khi kiểm tra cấu hình).

Và btw, nếu sử dụng ngoại trừ: Tôi sẽ luôn thêm ngoại lệ cụ thể cho nó (tại đây là ImportError) để không vô tình bắt lỗi không liên quan.

36

Phương pháp try: không cần phải toàn cầu - nó có thể được sử dụng trong bất kỳ phạm vi nào và vì vậy các mô-đun có thể "tải chậm" khi chạy. Ví dụ:

def foo(): 
    try: 
     import external_module 
    except ImportError: 
     pass 

    if external_module: 
     external_module.some_whizzy_feature() 
    else: 
     print "You could be using a whizzy feature right now, if you had external_module." 

Khi tập lệnh của bạn được chạy, sẽ không có nỗ lực để tải external_module. Lần đầu tiên foo() được gọi là, external_module là (nếu có) được nạp và chèn vào phạm vi địa phương của hàm. Các cuộc gọi tiếp theo để foo() reinsert external_module vào phạm vi của nó mà không cần phải tải lại mô-đun.

Nói chung, tốt nhất là để Python xử lý logic nhập - nó đã được thực hiện trong một thời gian. :-)

+8

Tôi nghĩ khối 'except ImportError' cần đặt' external_module = None' hoặc bạn sẽ nhận được 'NameError' khi bạn cố gắng truy cập nó trong khối if. – abhishekmukherg

+0

Giống như, hãy thử: ngoại trừ: (không có loại ngoại lệ), là một mẫu chống bắt, nhập khẩu có thể không phải là thứ bạn muốn. Nếu mô-đun tồn tại, nhưng tăng ngoại lệ, bạn sẽ bắt được và tiếp tục, ẩn lỗi. Tốt hơn hết là kiểm tra sự tồn tại của mô-đun, quyết định xem bạn có muốn nhập nó hay không, và sau đó * không * xử lý ImportError – user48956

0

Một cách để xử lý vấn đề phụ thuộc khác nhau cho các tính năng khác nhau là triển khai các tính năng tùy chọn dưới dạng plugin. Bằng cách đó, người dùng có quyền kiểm soát các tính năng nào được kích hoạt trong ứng dụng nhưng không chịu trách nhiệm tự theo dõi chính các phụ thuộc. Nhiệm vụ đó sau đó được xử lý tại thời điểm cài đặt mỗi plugin.

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