2014-02-18 212 views
2

我有一個包含兼容導入模塊的包。但是,我無法直接從公開的模塊導入;我必須使用稍微不方便的解決方法。從模塊變量導入Python

裏面常見/ compat.py,我有這樣的:

import bcrypt 

在main.py,這不起作用:

from common.compat.bcrypt import hashpw 

與錯誤:

Traceback (most recent call last): 
    File "main.py", line 2, in <module> 
    from common.compat.bcrypt import hashpw 
ImportError: No module named bcrypt 

但是,這工作正常:

from common.compat import bcrypt 
# now bcrypt.hashpw works fine 

有沒有辦法讓第一個工作正常工作,而無需做第二個解決方案?我寧願從相當多的類和方法進口。

回答

1

問題是bcrypt實際上並不是common.compat的子模塊;模塊對象實際上是common.compat模塊對象的成員屬性,其名稱bcrypt位於common.compat的名稱空間內。因此,如果您希望能夠導入bcrypt就好像它是一個子模塊common.compat而不是其名稱空間中的值,則需要繞過一點。您可以在封裝結構中創建一個虛擬bcrypt模塊,然後在其中包含from bcrypt import *以替代它,但可能更好的方法是直接修改compat.py中的sys.modules

import sys 
import bcrypt 

sys.modules['common.compat.bcrypt'] = bcrypt 

正如評論者所指出的,修改sys.modules是危險的。我從你調用包common.compat的事實推斷你正在創建某種兼容性模塊來實現備用邏輯,以防某些依賴不可用。相反黑客sys.modules的,你可能會得到更好的服務創造了common.compat.crypto模塊,看起來像

try: 
    from bcrypt import hashpw 
except ImportError: 
    # Alternative import, hand-written alternative, 
    # or function that raises NotImplementedError here 

然後在你的main.py,只是from common.compat.crypto import hashpw

+0

哎呀,不給他出主意有關修改'SYS .modules'就像這樣! :) - +1爲正確的解釋,但。 –

+0

請給我們一個很大的警告,那就是搞亂'sys。模塊'不是一個好主意,*特別是*如果OP不知道自己在做什麼(自從他問這個問題後他不知道)。 – Bakuriu

+0

@FerdinandBeyer和Bakuriu,更好? –

0

以下是你正在尋找的?

from common.compat import bcrypt.hashpw 

但是,它似乎是一個壞主意,建立這樣的方式depedencies,因爲你似乎並不需要一個compat.py甚至存在讓你bcrypt模塊。從普通/ compat.py腳本main.py

  1. 進口bcrypt.hashpw,作爲直接依賴
  2. 進口bcrypt就像你在你的最後片段
  3. 建議:因此,我寧願做下列之一
  4. 做一些與普通/ compat.py hashpw(如子類或包裝),並從compat.py導入子/包裝在main.py