2017-11-17 145 views
2

我們正在構建一個庫,其中的一部分是在不同系統上提供不同數據庫接口的模塊。如何在Python3中忽略未使用的導入

class DbInterface1(object): 
    """Uses MySQLdb, and is useful on system A.""" 
    def __init__(): 
     pass 

class DbInterface2(object): 
    """Uses SQLAlchemy, and is useful on system B.""" 
    def __init__(): 
     pass 

我們想要跳過未使用的導入。例如,在具有MySQLdb的系統上,我們將使用DbInterface1,並且不應要求安裝SQLAlchemy。也就是說,在系統中,我們會使用這樣的:顯然

from ourlibrary.dbinterfaces import DbInterface1 

... 

,這是不行的:

import MySQLdb 
import sqlalchemy 

class DbInterface1(object): 
    """Uses MySQLdb, and is useful on system A.""" 
    def __init__(): 
     pass 

class DbInterface2(object): 
    """Uses SQLAlchemy, and is useful on system B.""" 
    def __init__(): 
     pass 

我們認爲移動進口到使用它們將工作的類,因爲庫客戶端不會導入它沒有使用的東西,但它依然失敗。

class DbInterface1(object): 
    """Uses MySQLdb, and is useful on system A.""" 
    import MySQLdb 

    def __init__(): 
     pass 

class DbInterface2(object): 
    """Uses SQLAlchemy, and is useful on system B.""" 
    import sqlalchemy 

    def __init__(): 
     pass 

這樣做的正確方法是什麼?它甚至有可能嗎?

+3

嘗試將'import'移動到'__init __()'中,以便在類的實例創建之前不會導入。如果這還不夠,那麼這裏有更多的工具:https://docs.python.org/3/library/modules.html – gammazero

+0

@gammazero如果我們爲使用它們的每個函數添加導入(理想情況下我們可以只有'__init __()',但現在不正確)。我們可以使用'importlib.util.find_spec()'在導入之前檢查模塊的存在,但是如果模塊從應該安裝模塊的系統中丟失,那會導致意想不到的結果(也就是說,如果系統A由於某種原因缺少'MySQLdb')。所以你給了我們兩個工作選擇:--D,但都不是理想的。 – Kittsil

回答

1

爲什麼你不把你的進口包裝在try-except塊中?

try: 
    import MySQLdb 
except ImportError: 
    pass 
try: 
    import sqlalchemy 
except ImportError: 
    pass 

即使沒有安裝任何模塊,這應該允許運行腳本。

您可以修改上述方法來跟蹤導入的模塊是否存在以驗證某個類是否可以在某個系統上使用。

try: 
    import MySQLdb 
except ImportError: 
    module_MySQLdb = False 
else: 
    module_MySQLdb = True 

然後,您可以將該信息存儲在類變量中,並在實例化類之前檢查它。

class DbInterface1(object): 
    """Uses MySQLdb, and is useful on system A.""" 
    is_avaliable = module_MySQLdb 
    def __init__(self): 
     pass 

if DbInterface1.is_avaliable: 
    dbm = DbInterface1() 

或者你可以使用字典(如avaliable_modules = {'MySQLdb':module_MySQLdb}),並與你的類一起導入。

from ourlibrary.dbinterfaces import DbInterface1, avaliable_modules 

if avaliable_modules['MySQLdb']: 
    dbm = DbInterface1() 
+0

由於使用'find_spec()',如果模塊未安裝在預期的系統上並且因此不太理想,則會隱藏錯誤。 – Kittsil

+0

是的,但你可以使用一個變量來存儲信息(有點'哈克',我知道)。我更新了我的帖子以舉例。 –