好的,我们举个例子(下面的原始问题)。
我制作了一个名为“myproject”的软件包,它显示了我面临的问题。
你们其中一个人能够解释我的错误吗? Andrew Alcock 的回答并没有帮助我解决它,或者至少我没有看到问题出在哪里。
当然,通过这样一个简单的示例,包__init__.py
文件不需要那么复杂,但在我的真实项目中,我需要通过{{COOL
实例访问myproject.COOL
实例。 1}}。
感谢您的回答!
编辑:我已经授予 utapyngo 赏金,因为他的解决方案很有效,而且我学到了更多东西(相对于深子模块的导入)。但是我要感谢 Andrew 和 nehz 的答案( nehz 也提供了一个解决方案来解决我的问题,但我非常主观地找到了它“不那么漂亮”; Andrew 提供了有用的建议。太糟糕了,我无法分享赏金。
**
**
我不确定我是否正确地表达了这个问题。我创建了一个包含许多子包的大型代码,为简单起见,我们将其称为“CODE”。
问题是:'CODE'出现在名称空间中,所以我可以CODE.CODE
或CODE.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.py
不会从CODE或任何其他可能导入OBJ
的模块导入OBJ
。
init.py
可以导入mytools.py
等模块。
最后,像module.py
这样的模块可以导入mytools.py
或OBJ
(来自CODE)。通常,所有导入都是使用绝对导入进行的,例如:from CODE.sub.module import func
。
有没有人对这种行为有解释?我没有在SO上找到任何相关问题,但可能是由于我的错误措辞。
答案 0 :(得分: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不喜欢这种情况,因为它会导致混淆。
通常,所有导入都是使用绝对导入进行的,例如:来自CODE.sub.module import func。
行
答案 1 :(得分: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
编辑: FYI删除引用将不会卸载模块,并且COOL中的实例仍然有效。
答案 2 :(得分: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']