2009-08-11 28 views
5

我有我自己的模塊中重寫問題內建在Python的人(特別是日誌記錄模塊)。這裏是我的項目佈局:另一個絕對進口問題

run.py 
package/ 
     __init__.py 
     logging/ 
       __init__.py 
     ... 

run.py

from package import main 

main() 

包/ __ init__.py

from __future__ import absolute_import 
import logging 
import logging.config 

def main(): 
    logging.config.fileConfig(...) 

包/日誌/ __ init__.py

class Logging(object): 
    pass 

因爲它現在站立,上面的代碼工作。當我嘗試從package.logging像這樣導入日誌類:

from __future__ import absolute_import 

import logging 
import logging.config 
from package.logging import Logging 

def main(): 
    logging.config.fileConfig(...) 

我得到一個錯誤:

AttributeError: 'module' object has no attribute 'config' 

我讀過PEP 328發行說明,發現絕對進口是相當直接。不幸的是,我一直無法弄清楚這一點。

我在這裏錯過了什麼?

回答

1

您可以使用relative imports迫使地方蟒蛇查找模塊第一:

in package/__init__.py

from . import logging 
+0

使用你的例子確實出現了工作。但是,我現在必須將Logging類稱爲logging.Logging。進一步的測試表明,「從.logging導入記錄」看起來並不像PEP 328所示。我仍然不明白爲什麼「從package.logging導入日誌記錄」不起作用。這不是絕對的進口嗎? – kierse 2009-08-11 23:57:02

+0

你使用的是什麼版本的python?如果它的舊版本(比如說2.4)相對導入可能不起作用,或者至少不起作用。 – Soviut 2009-08-12 01:40:55

+0

我正在運行Python 2.6.2 – kierse 2009-08-12 19:31:01

9

相對和絕對進口(PEP 328)是不是這裏的問題。

會發生什麼事是,當在一個封裝的模塊是進口的,它默認添加到這個包的命名空間。所以

from package.logging import Logging 

不僅增加了「日誌記錄」包。 _dict _,而且還增加了「記錄」(新導入本地模塊)封裝。 _dict _。因此,您首先導入日誌記錄(頂層模塊),並將其作爲package.logging提供,然後使用本地模塊覆蓋此變量。這基本上意味着您不能像預期的那樣有package.logging來訪問頂級模塊和本地模塊。

在這種特定的情況下,你可能不希望「出口」頂級記錄模塊作爲一個公共的名字。相反,這樣做:

from logging import config as _config 
def main(): 
    _config.fileConfig(...) 
+0

哇,剛剛學會了一個新的Python陷阱。我需要自己測試一下,這完全如你所說。如果有人想驗證這一點,只需在'package.logging import Logging'後面加'print logging'。 – 2012-01-16 13:38:39