2009-07-29 91 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