从库中深入导入包含子模块的模块

时间:2009-07-29 11:58:04

标签: python coding-style

在办公室,我们有一个以公司名称命名的库和其子库内,每个项目或多或少,并且在每个子库中可能有更多的模块或库。我们正在使用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

3:

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

第一种风格只导入models?当前名称空间中可用的名称specificbase是什么?

如果导入第一个子模块并且之后只导入包含的库,模块初始化会发生什么?

也许最新的风格是最后一个,我很清楚(至少对我来说)我首先导入两个模块并将其名称直接放在当前命名空间中,第二个导入添加model刚刚导入的两个模块的子模块。

另一方面,(1)允许我只导入内部模块并以紧凑而明确的方式引用它们(specific.modelsbase.models

不确定这是否有问题,但我很想阅读评论。

2 个答案:

答案 0 :(得分: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等。如果“具体”是a,您还需要在import model中执行__init__.py才能访问specific.module。

答案 1 :(得分: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__.py中的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
importing D
>>> 

导入包含的模块可能最好在包初始化结束时完成。


考虑到这一切,并考虑到一些特定的django行为(这使得导入包时很难/不可能自动import models),我认为我更喜欢样式3。