4

好的,让我们举个例子(下面的原始问题)。

我制作了一个名为“myproject”的包,它显示了我面临的问题。

  1. 在此处下载包:https ://dl.dropbox.com/u/11013311/myproject.zip
  2. 安装包(例如:sudo python setup.py develop)
  3. 打开一个 Ipython 会话并输入:“import myproject”
  4. 如果您开始输入“myproject”。并点击两次选项卡以获取可用的方法/值...,您会看到“myproject.myproject”,它自己也显示出同样的问题。

你们中的一个人能够解释我做错了什么吗?Andrew Alcock的回答并不能帮助我解决这个问题,或者至少我看不出问题出在哪里。

当然,通过这样一个简单的示例,包__init__.py文件不需要那么复杂,但是在我的实际项目中,我确实需要COOL通过myproject.COOL.

感谢您的回答!

编辑:我奖励了utapyngo赏金,因为他的解决方案是有效的,而且我学到了更多东西(具有深度子模块的相对导入)。但我要感谢Andrewnehz的回答(nehz还提供了解决我的问题的解决方案,但主观上我觉得它“不那么漂亮”;Andrew提供了有用的建议)。可惜我不能分享赏金。

**

原始问题:

**

我不确定我是否正确地表达了这个问题。我创建了一个包含许多子包的大型代码,为简单起见,我们将其称为“代码”。

问题是: 'CODE' 出现在命名空间中,所以我可以拥有CODE.CODEorCODE.CODE.CODE等​​...无限次,这对我来说看起来很奇怪,并且可能(我猜)暗示有问题(尽管代码运行良好没有警告)。

我猜这个问题与我__init__.py和我的代码结构有关,所以我在这里提供更多信息。

简化的代码结构:

CODE
  | __init__.py
  | tools
     | __init__.py
     | mytools.py
  | other
     | __init__.py
     | init.py
  | sub
     | __init__.py
     | module.py

文件:(__init__.py第一个,在根目录CODE

import CODE.tools.mytools as MyTools
import CODE.other.init

OBJ = CODE.other.init.function()
...

该文件mytools.pyOBJ从 CODE 或任何其他可能导入的模块导入OBJinit.py可以导入模块,例如mytools.py. 最后,类似的模块module.py可以导入mytools.pyOBJ(从 CODE)。通常,所有导入都是使用绝对导入进行的,例如 in: from CODE.sub.module import func

有人对这种行为有解释吗?我没有找到关于 SO 的任何相关问题,但这可能是由于我的措辞错误。

4

3 回答 3

3

问题是您导入的(基本上是顶级 __init__.py 文件)在其他导入中包含对自身(模块)的引用。由于模块现在有一个包含自身的名称空间,因此您现在可以以 CODE.CODE 的形式访问它。... .CODE.MyTools。

我会建议:

1)在每个子包(工具,其他)中都有一个 __init__.py

2) 在 CODE 的模块中,不要“导入 CODE”或任何子包。而是直接导入您感兴趣的模块(文件)。

例如,在 CODE.sub.module.py 中:

不要:

import CODE.other     # "other" is a package (a directory)

做:

import CODE.other.init    # "init" is a module (a file)

理智就是这样。

编辑:重新构建您的具体示例

文件 mytools.py 不会从 CODE 或任何其他可能导入 OBJ 的模块中导入 OBJ。init.py 可以导入 mytools.py 等模块。

好的

最后,像 module.py 这样的模块可以导入 mytools.py 或 OBJ(来自 CODE)。

这是你的问题。不要在此处导入 CODE。如果您需要简化相当长的“CODE.other.init.function”,您可以使用 from .. import 语句来完成:

> from CODE.other.init import function as OBJ 

但是请注意,许多 Pythonite 不喜欢这个,因为它会导致混乱。

通常,所有的导入都是用绝对导入进行的,例如:from CODE.sub.module import func。

好的

于 2012-07-17T01:25:25.667 回答
1

使用绝对导入后只需删除引用:

import atexit

import myproject.mymodule_one.suby as SubY
obj = SubY.myclass()
import myproject.mymodule_two.initialization

COOL = myproject.mymodule_two.initialization.create_cool()
del myproject

编辑:仅供参考,删除引用不会卸载模块,并且 COOL 中的实例仍然有效。

于 2012-08-31T03:45:24.230 回答
1

在您的主目录__init__.py中,您不必甚至不应该引用您的模块名称(谁知道,您将来可能想要重命名它)。

只需更换

import myproject.mymodule_...

import mymodule_...

现在没有myproject.myproject

>>> dir(myproject)
['COOL', 'SubY', '__builtins__', '__doc__', '__file__', '__name__', '__package__',
 '__path__', '__version__', 'atexit', 'exit_report', 'mymodule_one', 'mymodule_two',
 'obj', 'toto']
于 2012-08-31T12:02:34.820 回答