2010-03-09 70 views
3

我有一套相當簡單的功能,我有多個實現,例如可以由Redis,MongoDB或PostgreSQL支持的數據存儲。我應該如何構建/編寫我的代碼,以便希望使用這些實現之一的代碼只需要該實現的依賴關係,例如,如果他們使用的是Redis後端,則不需要安裝psycopg2如何僅支付您在Python中使用的實現的依賴性懲罰?

下面是一個例子。假設以下模塊,example.py

class RedisExample(object): 
    try: 
     import redis 
    except ImportError: 
     print("You need to install redis-py.") 

    def __init__(self): 
     super(RedisExample, self).__init__() 

class UnsatisfiedExample(object): 
    try: 
     import flibbertigibbet 
    except ImportError: 
     print("You need to install flibbertigibbet-py") 

    def __init__(self): 
     super(UnsatisfiedExample, self).__init__() 

這裏是我的Python shell的體驗:

>>> import example 
You need to install flibbertigibbet-py 

或者:

>>> from example import RedisExample 
You need to install flibbertigibbet-py 

我真的寧願我沒有,直到我試圖實例化一個UnsatisfiedExample得到這個錯誤。有沒有什麼常見的方法來解決這個問題?我曾考慮過讓每個後端都有自己的模塊並使用工廠功能來製作example,但我想確保我不會錯過更好的東西。

謝謝。

+2

有了這樣一個驚人的代表你的整個問題是在標題...? –

+0

這可能有助於集中標題並在正文中提供詳細信息。細節幫助,一些幾乎可用的代碼來顯示你希望發生的事情通常是有幫助的。 –

+0

對不起 - 我有一個新生兒,所以專注的能力在這裏是一分鐘,接下來就是了。我會嘗試修改。 –

回答

5

難道你不能簡單地把import聲明放在每個類的__init__方法中嗎?然後它將不會運行,直到你試圖做一個實例:

class UnsatisfiedExample(object): 
    def __init__(self): 
     try: 
      import flibbertigibbet 
     except ImportError: 
      raise RuntimeError("You need to install flibbertigibbet-py") 
     super(UnsatisfiedExample, self).__init__() 
+0

此外,您可以將lib存儲在實例變量中,以便稍後在您的類中進行訪問:''try:import flibbertigibbet; self.fg = flibbertigibbet''' – gaborous

4

import只是另一種說法,如forwith。將其置於if語句中,可能位於抽象類的後面。

+0

我修改了這個問題以提供更多細節。你能否提供你提到的抽象類想法的例子,以及這將如何解決我的(現在希望更清楚)關注? –

+0

我的答案沒有改變。在需要時執行導入。 –

+0

您是否暗示客戶端代碼只是'從示例導入RedisExample'而不是'import example'?因爲這也會觸發'ImportError'。 –

相關問題