为什么“导入模块”然后“从包导入模块”再次加载模块?

为什么“导入模块”然后“从包导入模块”再次加载模块?

问题描述:

我在我的PYTHONPATH一个包,看起来是这样的:为什么“导入模块”然后“从包导入模块”再次加载模块?

package/ 
    __init__.py 
    module.py 
     print 'Loading module' 

如果我从package/目录中运行的Python(或写在这个目录中的另一个模块),然后键入

import module 

它加载module.py并按预期打印出“加载模块”。但是,如果我再键入

from package import module 

它加载module.py并打印“加载模块” 再次,我不指望。这是什么原理?

注:我想我明白技术上为什么Python这样做,因为import module这个sys.modules关键就是"module",但from package import module"package.module"。所以我想我想知道的是为什么这里的关键是不同的 - 为什么不把文件的路径名称用作关键字,这样Python就可以做到这一点?

+2

想想只使用文件名称的含义是:这意味着两个软件包不能包含同名文件,因为第二个导入会导入第一个导入的文件! – delnan 2011-06-08 16:56:02

+0

@delnam,真的,但我的意思是“完整路径名” - 编辑的问题来澄清。 – 2011-06-08 17:02:20

+0

为什么不直接使用'module = package.module',如果你真的不想再导入它呢? – geoffspear 2011-06-08 17:02:48

实际上,通过运行package目录中的代码,您错误地配置了Python。您不应该将该目录放在sys.path上,因为它位于包内。

Python不使用文件名作为密钥,因为它没有导入文件,而是导入模块。允许人们做'import c:\jim\my files\projects\code\stuff'会鼓励各种各样的混乱。

考虑这种情况下,而不是:如果你是在~/foo/package/~/bar是在PYTHONPATH - 但是〜/酒吧仅仅是一个符号链接到~/foo?您是否期望Python能够解决,然后为您重复删除符号链接?如果你把一个相对目录放在PYTHONPATH上,然后改变目录呢?如果'foo.py'是'bar.py'的符号链接呢?你是否期望这两种方式也被去重?如果他们不是符号链接,但只是确切的副本?增加复杂的规则以尝试在模糊的环境中做一些方便的事情意味着它会对其他人造成极大的不便。 (Python 12:面对模棱两可,拒绝猜测的诱惑)

Python在这里做了一些简单的事情,确保环境设置正确是您的责任。现在,你可以争辩说,默认情况下将当前目录放在PYTHONPATH上不是一个好主意 - 我甚至可能会同意你的看法 - 但鉴于它在那里,它应该遵循与其他路径条目相同的一组规则。如果它打算从任意目录运行,那么应用程序始终可以从中删除当前目录,并以sys.path.remove('')开头。

这是当前模块系统的一个小缺陷。

导入模块时,可以从当前没有名称的命名空间执行。该命名空间中的值与中的值相同,但解释器无法知道它。

当导入package.module时,您从程序包命名空间导入模块。

这就是main.py应该在包forlder之外的原因。 许多模块有这样的组织:

package/
    main.py 
    package/
     sub_package1/ 
     sub_package2/ 
     sub_package3/ 
     module1.py 
     module2.py 

只调用的main.py确保命名空间的设置是否正确,又名当前命名空间是main.py的。它无法在module2.py中调用import module1.py。您需要致电import package.module1。使事情变得简单和均匀。

是的,导入当前文件夹作为当前无名文件夹是一个坏主意。 如果你超越了几个脚​​本,这是一个PITA。但是随着Python开始,它并不完全没有意义。