2009-07-29 105 views
0

在辦公室,我們有一個以公司名稱命名的庫和它的子庫內部,每個項目或多或少,並且在每個子庫中可能有更多的模塊或庫。我們使用Django的,這使得我們的層次結構中的幾個步驟更深......從庫中深入導入子模塊

我有點困擾有關以下導入說明之間的差異:

1:

 
import company.productline.specific.models, company.productline.base.models 
specific, base = company.productline.specific, company.productline.base 
2:

 
import company.productline.specific.models, company.productline.base.models 
from company.productline import specific, base 
只有

 
from company.productline import specific, base 
import company.productline.specific.models, company.productline.base.models 

第一個樣式進口models

3?那麼在當前名稱空間中提供的名稱是specificbase

如果一個模塊導入第一個子模塊並且只有後面的包含庫,模塊的初始化會發生什麼?

也許最巧妙的風格是最後一個,它是明確的(至少對我來說),我先導入兩個模塊,並直接把他們的名字在當前名字空間和第二進口增加了model子模塊既剛剛導入的模塊。

在另一方面

,(1)讓我只導入內部模塊,並指他們在一個緊湊的,雖然明路(specific.modelsbase.models

不太確定這是否是問題,但我很想讀評論。

回答

0

所以我看着它深一點,使用這種沒用進一步包:

A:(__init__.py: print 'importing A', 
    B:(__init__.py: print 'importing B', 
     C1:(__init__.py: print 'importing C1', 
      D:(__init__.py: print 'importing D')) 
     C2:(__init__.py: print 'importing C2', 
      D:(__init__.py: print 'importing D')))) 

通知,C1C2包含兩個不同的模塊,並重命名爲他們不同的命名空間D。我會同時需要它們,我不想使用ABC1.D和ABC2.D的整個路徑,因爲它看起來太笨拙,我不能把它們都放在當前命名空間中,因爲它會覆蓋另一個命名空間,不 - 我不喜歡改變他們的名字的想法。我想要的是在當前命名空間中有C1C2,並加載包含D模塊的兩個模塊。

哦,是的:我希望代碼可讀。

我嘗試了兩種形式

from A.B import C1 

和更噁心一個

import A.B.C1 
C1 = A.B.C1 

,我會認爲,他們是等價的:


Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 
>>> from A.B import C1 
importing A 
importing B 
importing C1 
>>> C1 
<module 'A.B.C1' from 'A/B/C1/__init__.pyc'> 
>>> 

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 
>>> import A.B.C1 
importing A 
importing B 
importing C1 
>>> C1=A.B.C1 
>>> C1 
<module 'A.B.C1' from 'A/B/C1/__init__.pyc'> 
>>> 

導入包C1或C2不會導入包含的模塊,只是因爲它們在那裏。而且形式from A.B import C1.D也沒有語法上的接受:那可能是一個很好的緊湊的東西。

另一方面,如果我願意,我有機會在A.B.C1.__init__.py這樣做。所以,如果我行import D追加到__init__.pyA.B.C1,這是發生了什麼:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 
>>> from A.B import C1 
importing A 
importing B 
importing C1 
importing D 
>>> 

進口包含的模塊可能最好在包初始化結束時進行。


考慮到這一切,並給出一些具體的Django的行爲(這使得它難以/不可能自動import models在導入包),我想我更喜歡的風格3.

0

以上三個例子在實踐中都是等價的。儘管如此,它們都很奇怪。沒有理由做

from company.productline import specific 

import company.productline.specific.models 

你可以(大部分時間)剛剛訪問模式由specific.models首次進口之後。

似乎有理由在這種情況下做

from company.productline import base 
from company.productline import specific 

,然後訪問這些像base.modelsspecific.whatever等,如果「特殊」是你還需要在__init__.pyimport model能夠訪問specific.module。

+0

我看了一下標準電子郵件包,其中包含各種深層次的模塊,並且它沒有定義`__all__`(僅適用於`from package import *`),相反,它使用懶惰的導入做了一些奇特的事情......非常有趣。嘗試了一個包含`import models`的`__init __。py`,但是當python導入模型時,django會在後臺執行什麼操作,這使得不可能這樣做(django掃描INSTALLED_APPS並假定它們已經存在,而python仍在導入它) – mariotomo 2009-07-29 13:35:04