Python 防止包自身导入
好的,让我们给你一个例子(下面的原始问题) 我制作了一个名为“myproject”的包,它显示了我所面临的问题Python 防止包自身导入,python,namespaces,Python,Namespaces,好的,让我们给你一个例子(下面的原始问题) 我制作了一个名为“myproject”的包,它显示了我所面临的问题 请在此处下载软件包: 安装软件包(例如:sudo python setup.py develope) 打开Ipython会话并键入:“导入myproject” 如果您开始键入“myproject.”并按tab键两次以获取可用的方法/值…,您将看到“myproject.myproject”,它本身也显示了相同的问题 你们当中有人能解释我做错了什么吗?Andrew Alcock的回答无助于
\uuuu init\uuuu.py
文件就不需要那么复杂,但在我的实际项目中,我确实需要COOL
实例通过myproject.COOL
访问
谢谢你的回答
编辑:我授予乌塔平戈奖金,因为他的解决方案很有效,我学到了更多东西(与深子模块的相对导入)。但我要感谢Andrew和nehz的回答(nehz也提供了一个解决方案,解决了我的问题,但主观上我觉得它“不太漂亮”;Andrew提供了有用的建议)。可惜我不能分享这笔赏金
**
原始问题:
**
我不确定这个问题的措辞是否正确。我创建了一个包含许多子包的大型代码,为了简单起见,我们称之为“代码”
问题是:“CODE”出现在名称空间中,因此我可以使用CODE.CODE
或CODE.CODE.CODE
,等等。。。无数次,这对我来说很奇怪,并且可能(我猜)是某种错误的暗示(尽管代码在没有警告的情况下工作得很好)
我想这个问题与我的\uuuu init\uuuuuy.py
和我的代码结构有关,所以我在这里提供了更多的信息
简化代码结构:
CODE
| __init__.py
| tools
| __init__.py
| mytools.py
| other
| __init__.py
| init.py
| sub
| __init__.py
| module.py
文件:\uuuu init\uuuuu.py
(第一个,在代码的根目录下)
文件mytools.py
不从code或任何其他可能导入OBJ
的模块导入OBJ
。
init.py
可以导入模块,如mytools.py
。
最后,像module.py
这样的模块可以导入mytools.py
或OBJ
(来自代码)。通常,所有导入都是使用绝对导入进行的,例如在:from code.sub.module import func
中
有人对这种行为有什么解释吗?我没有发现任何与此相关的问题,但这可能是因为我的措辞错误。问题是,您导入的包(基本上是顶级的init.py文件)在其他导入中包含对自身(模块)的引用。由于模块现在有一个自己的名称空间,您现在可以作为CODE.CODE…..访问它。CODE.MyTools
我建议:
1) 在每个子包(工具、其他)中都有一个_uinit__uuuuuuu.py
2) 在代码的模块中,不要“导入代码”或任何子包。而是直接导入您感兴趣的模块(文件)
例如,在CODE.sub.module.py中:
不要:
import CODE.other # "other" is a package (a directory)
做:
这样的话,理智就是谎言
编辑:重新构建您的特定示例
mytools.py文件不从代码或任何其他可能导入OBJ的模块导入OBJ。init.py可以导入mytools.py等模块
嗯
最后,module.py之类的模块可以导入mytools.py或OBJ(从代码)
这是你的问题。不要在这里导入代码。如果需要简化相当长的“CODE.other.init.function”,可以使用from。。进口声明:
> from CODE.other.init import function as OBJ
但要知道,许多蟒蛇不喜欢这样,因为这会导致混乱
通常,所有导入都使用绝对导入,例如:from CODE.sub.module import func
好的使用绝对导入后,只需删除引用即可:
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中的实例仍然有效。在主\uuuu init\uuuuuuuupy.py
中,您不必甚至不应该引用您的模块名称(谁知道,您将来可能会想重命名它)
替换
import myproject.mymodule_...
与
现在没有myproject.myproject
:
>>> dir(myproject)
['COOL', 'SubY', '__builtins__', '__doc__', '__file__', '__name__', '__package__',
'__path__', '__version__', 'atexit', 'exit_report', 'mymodule_one', 'mymodule_two',
'obj', 'toto']
考虑到共享部分是最好的答案……我下载了代码并运行了python setup.py developer。然而,我无法在我的环境中重现这个问题,特别是从命令行和PyCharm内部。具体来说,Python在发出“import myproject.myproject”语句时失败。我对lpython没有任何经验,但问题可能是lpython本身吗?@Andrew,我在IPython和普通python中都复制了它:>>>导入myproject;myproject.myproject@Andrew,奇怪。。。作为utapyngo,我在常规python解释器和IPython中都遇到了问题。虽然我从未在脚本中测试过这个问题。@Andrew,是的,我只是在脚本中进行了检查,在导入myproject.myproject
时确实出现了一个错误。也许它只与python解释器相关,但为什么呢?谢谢你的回答。首先,我在每个子包中都有\uuuu init\uuuu.py
文件(我只是没有把它们放在我给你的简化结构中,我的坏朋友)。然后我认为我没有任何主包本身(代码)或任何子包的导入。正如我所说,我使用绝对导入,但我肯定要检查两次,因为你说这可能是我问题的原因:)最后,我不理解你的第二点OBJ
是函数function()
的结果,而不是重命名。非常感谢您的投入!我想我们知道了一些事情。在_uinit__uuuuuy.py中声明的所有名称对该包的进口商都可见,因此任何进口该包的人都可以看到OBJ
import myproject.mymodule_...
import mymodule_...
>>> dir(myproject)
['COOL', 'SubY', '__builtins__', '__doc__', '__file__', '__name__', '__package__',
'__path__', '__version__', 'atexit', 'exit_report', 'mymodule_one', 'mymodule_two',
'obj', 'toto']